#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 999999999999999999
#define MAXN 300005

struct node
{
    ll prop;
    ll x;
    ll sum;
};

ll N, Q, ans;
ll arr[MAXN];
node tree[4 * MAXN];

void push(ll n, ll l, ll r)
{
    ll mid = (l + r) / 2;
    ll p = tree[n].x;

    tree[n].x = 0;
    tree[n].prop = 0;

    tree[2 * n].sum = (mid - l + 1) * p;
    tree[2 * n + 1].sum = (r - mid) * p;

    tree[2 * n].prop = 0;
    tree[2 * n].x = p;

    tree[2 * n + 1].prop = 0;
    tree[2 * n + 1].x = p;
}

void build(ll n, ll l, ll r)
{
    if(l == r)
    {
        tree[n].prop = 0;
        tree[n].x = 0;
        tree[n].sum = arr[l];
        return ;
    }

    ll mid = (l + r) / 2;
    build(2 * n, l, mid);
    build(2 * n + 1, mid + 1, r);

    tree[n].x = 0;
    tree[n].prop = 0;
    tree[n].sum = tree[2 * n].sum + tree[2 * n + 1].sum;
}

void update_by(ll n, ll l, ll r,ll i, ll j, ll val)
{
    if(l > j or r < i)
        return ;

    if(l != r and tree[n].x)
        push(n, l, r);

    if(l >= i and r <= j)
    {
        tree[n].sum += (val * (r - l + 1));
        tree[n].prop += val;
        tree[n].x = 0;
        return ;
    }

    ll mid = (l + r) / 2;
    update_by(2 * n, l, mid, i, j, val);
    update_by(2 * n + 1, mid + 1, r, i, j, val);
    tree[n].sum = tree[2 * n].sum + tree[2 * n + 1].sum + ((r - l + 1) * tree[n].prop);
}

void update_to(ll n, ll l, ll r, ll i, ll j, ll val)
{
    if(l > j or r < i)
        return ;

    if(l != r and tree[n].x)
        push(n, l, r);

    if(l >= i and r <= j)
    {
        tree[n].prop = 0;
        tree[n].x = val;
        tree[n].sum = val * (r - l + 1);
        return ;
    }

    ll mid = (l + r) / 2;
    update_to(2 * n, l, mid, i, j, val);
    update_to(2 * n + 1, mid + 1, r, i, j, val);
    tree[n].sum = tree[2 * n].sum + tree[2 * n + 1].sum + ((r - l + 1) * tree[n].prop);
}

ll query(ll n, ll l, ll r, ll i, ll j, ll val = 0)
{
    if(l > j or r < i)
    {
        return 0;
    }

    if(l != r and tree[n].x)
        push(n, l, r);

    if(l >= i and r <= j)
    {
        return tree[n].sum + val * (r - l + 1);
    }
    

    ll mid = (l + r) / 2;
    ll p = tree[n].prop;
    ll a = query(2 * n, l, mid, i, j, val + p);
    ll b = query(2 * n + 1, mid + 1, r, i, j, val + p);
    return a + b;
}

void solve()
{
    cin >> N >> Q;
    for(ll i = 1; i <= N; ++ i)
    {
        cin >> arr[i];
    }

    N = 1 << (ll) ceil(log2(N));
    build(1, 1, N);

    for(ll i = 1; i <= Q; ++ i)
    {
        ll tt;
        cin >> tt;

        if(tt == 1)
        {
            ll a, b, x;
            cin >> a >> b >> x;
            update_by(1, 1, N, a, b, x);
        }
        else if(tt == 2)
        {
            ll a, b, x;
            cin >> a >> b >> x;
            update_to(1, 1, N, a, b, x);
        }
        else
        {
            ll a, b;
            cin >> a >> b;
            cout << query(1, 1, N, a, b) << endl;
        }
    }
    return ;
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    // freopen("input.txt","r",stdin);
    // freopen("output.txt","w",stdout);

    solve();
    return 0;
}
