#include <bits/stdc++.h>
#define int long long
using namespace std;
int st[1000005];
pair<int, int>lazy[1000005];
void build(int node, int l, int r, int pos, int val)
{
if(l==r)
{
st[node]=val;
return;
}
int mid=(l+r)/2;
if(pos<=mid)
build(node*2, l, mid, pos, val);
else
build(node*2+1, mid+1, r, pos, val);
st[node]=st[node*2]+st[node*2+1];
}
void propagate(int node, int l, int r)
{
if(lazy[node].first)
st[node]=(r-l+1)*lazy[node].first;
st[node]+=(r-l+1)*lazy[node].second;
if(l!=r)
{
if(lazy[node].first)
lazy[node]=lazy[node*2]=lazy[node*2+1];
else if(lazy[node].second)
{
lazy[node*2].second+=lazy[node].second;
lazy[node*2+1].second+=lazy[node].second;
}
}
lazy[node]={0, 0};
}
void update(int l, int r, int node, int ql, int qr, int val, int cer)
{
propagede(node, l, r);
if(ql>r || qr<l)
return;
if(ql<=l && qr<=r)
{
if(cer==2)
lazy[node]={val, 0};
else
lazy[node].second+=val;
propagate(node, l, r);
return;
}
int mid=(l+r)/2;
update(l, mid, node*2, ql, qr, val, cer);
update(mid+1, r, node*2+1, ql, qr, val, cer);
st[node]=st[node*2]+st[node*2+1];
}
int query(int l, int r, int node, int ql, int qr)
{
propagate(node, l, r);
if(ql<=l && r<=qr)
return st[node];
int mid=(l+r)/2, s=0;
if(ql<=mid)
s+=query(l, mid, node*2, ql, qr);
else
s+=query(mid+1, r, node*2+1, ql, qr);
return s;
}
signed main()
{
int n, q, a, b, x, tip;
cin>>n>>q;
for(int i=1; i<=n; i++)
{
cin>>a;
build(1, 1, n, i, a);
}
while(q--)
{
cin>>tip;
if(tip==1)
{
cin>>a>>b>>x;
update(1, n, 1, a, b, x, 1);
}
else if(tip==2)
{
cin>>a>>b>>x;
}
else
{
cin>>a>>b;
}
}
return 0;
}