CSES - Shared codeLink to this code: https://cses.fi/paste/61cbf01db11bfa6a8827de/
#include <bits/stdc++.h>
 
#define range(it, a, b) for (ll it = a; it < b; it++)
#define all(x) begin(x), end(x)
#define ll long long
#define ull unsigned long long
#define INF64 ((ll) 1 << 62)
#define INF32 (1 << 30)
#define mset multiset
#define uset unordered_set
#define umap unordered_map 
#define pqueue priority_queue 
#define ptr(A) shared_ptr<A>
 
using namespace std;
 
void setio (string name) {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    if (name.size()) {
        freopen((name + ".in").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
}

struct SegTree {
    struct Node {
        Node* left;
        Node* right;
        ll l, r, sum;
        ll lazy_set = -1, lazy_sum = 0;
        ll get_m() { return (l+r)/2; }
        ll size() { return r-l+1; }
    };

    Node* root;
    vector<ll>& arr;

    SegTree (vector<ll>& a) : arr(a) {
        root = new Node;
        root->l = 0;
        root->r = a.size()-1;
        build(root);
    }

    void build(Node* node) {
        if (node->l == node->r) {
            node->sum = arr[node->l];
            return;
        }

        node->left = new Node;
        node->left->l = node->l;
        node->left->r = node->get_m();
        build(node->left);

        node->right = new Node;
        node->right->l = node->get_m()+1;
        node->right->r = node->r;
        build(node->right);

        node->sum = node->left->sum + node->right->sum;
    }

    void push(Node* node) {
        if (node->lazy_set != -1 || node->lazy_sum > 0) {
            if (node->lazy_set != -1) {
                node->left->sum = node->left->size()*node->lazy_set;
                node->left->lazy_set = node->lazy_set;
                node->left->lazy_sum = 0;

                node->right->sum = node->right->size()*node->lazy_set;
                node->right->lazy_set = node->lazy_set;
                node->right->lazy_sum = 0;

                node->lazy_set = -1;
            }

            node->left->sum += node->left->size()*node->lazy_sum;
            node->left->lazy_sum += node->lazy_sum;
            node->right->sum += node->right->size()*node->lazy_sum;
            node->right->lazy_sum += node->lazy_sum;
            node->lazy_sum = 0;
        }
    }

    void update(Node* node, ll l, ll r, ll delta) {
        if (node->l == l && node->r == r) {
            node->sum += node->size()*delta;
            node->lazy_sum += delta;
            return;
        }

        push(node);
        if (l <= node->get_m())
            update(node->left, l, min(r, node->get_m()), delta);
        if (node->get_m() < r)
            update(node->right, max(l, node->get_m()+1), r, delta);

        node->sum = node->left->sum + node->right->sum;
    }

    void update_set (Node* node, ll l, ll r, ll x) {
        if (node->l == l && node->r == r) {
            node->sum = node->size()*x;
            node->lazy_set = x;
            node->lazy_sum = 0;
            return;
        }

        push(node);
        if (l <= node->get_m())
            update_set(node->left, l, min(r, node->get_m()), x);
        if (node->get_m() < r)
            update_set(node->right, max(l, node->get_m()+1), r, x);

        node->sum = node->left->sum + node->right->sum;
    }

    void update(ll l, ll r, ll delta) { update(root, l, r, delta); }
    void update_set(ll l, ll r, ll x) { update_set(root, l, r, x); }

    ll query(Node* node, ll l, ll r) {
        if (node->l == l && node->r == r) 
            return node->sum;
        
        push(node);
        ll ans = 0;
        if (l <= node->get_m())
            ans += query(node->left, l, min(r, node->get_m()));
        if (node->get_m() < r)
            ans += query(node->right, max(l, node->get_m()+1), r);
        return ans;
    }

    ll query(ll l, ll r) { return query(root, l, r); }
};

ll n, q;
vector<ll> arr;

void solve() {
    cin >> n >> q;
    arr.resize(n);

    range(i, 0, n)
        cin >> arr[i];
    SegTree st (arr);

    ll t;
    while (q--) {
        cin >> t;
        if (t == 1) {
            ll l, r, x;
            cin >> l >> r >> x;
            l--; r--;
            st.update(l, r, x);
            continue;
        }
        if (t == 2) {
            ll l, r, x;
            cin >> l >> r >> x;
            l--; r--;
            st.update_set(l, r, x);
            continue;
        }
        ll l, r;
        cin >> l >> r;
        l--; r--;

        cout << st.query(l, r) << '\n';
    } 
}
 
int main () {
    setio("");
    ll t = 1; 
    // cin >> t;
    while (t--) solve();
}
 
// IT'S TOUGH, I KNOW
// BUT YOU'D RATHER DIE FIGHTING THAN LIVE ON YOUR KNEES
// THOUG H YOU WON'T DO NEITHER OF THOSE
// IMPOSSIBLE, AS IT'S AGAINST YOUR NATURE
// AS YOU ALREADY WON
// I SEE YOUR MEDAL HANGING FROM YOUR NECK
// SHINING AS NOTHING YOU'VE EVER HAD
 
// THOUSANDS AND THOUSANDS OF LINES
// YOU AREADY MADE IT THIS FAR
// AND WHO COULD TELL HOW FAR YOU WILL GET...
// BUT YOU?
 
// THEN COME ON, YOU BASTARD!
// GO CLEAR YOUR MIND AND STAND
// AS EACH OF THOSE LINES IS A STEP CLOSER
// CLOSER TO THE GREATNESS YOU PURSUE
// CLOSER TO THE GREATNESS YOU ALREADY HAVE