#include<bits/stdc++.h>
using namespace std;
#define ls x<<1
#define rs x<<1|1
#define mid (l+r)/2
int const N=1e6+10;
int f[N<<2],a[N],la1[N],la[N];
void build(int x,int l,int r){
if (l==r){f[x]=a[l];return;}
build(ls,l,mid);
build(rs,mid+1,r);
f[x]=max(f[ls],f[rs]);
//cout<<x<<' '<<l<<' '<<r<<' '<<f[x]<<'\n';
}
void pushdown(int x){
if (la1[x]>=0){
f[ls]=f[rs]=la1[x];
la1[ls]=la1[rs]=la1[x];
la1[x]=0;
la[ls]=la[rs]=0;
}else{
la[ls]+=la[x];
la[rs]+=la[x];
la[x]=0;
f[ls]+=la[x];
f[rs]+=la[x];
}
}
void update(int x,int l,int r,int ll,int rr,int k){
if (ll<=l && r<=rr){
la[x]=0;
la1[x]=k;
f[x]=k;
return;
}
if (r<ll || l>rr) return;
pushdown(x);
if (mid<rr) update(rs,mid+1,r,ll,rr,k);
if (mid>=ll) update(ls,l,mid,ll,rr,k);
f[x]=max(f[ls],f[rs]);
}
void add(int x,int l,int r,int ll,int rr,int k){
if (ll<=l && r<=rr){
la[x]+=k;
f[x]+=k;
return;
}
if (r<ll || l>rr) return;
pushdown(x);
if (mid<rr) add(rs,mid+1,r,ll,rr,k);
if (mid>=ll) add(ls,l,mid,ll,rr,k);
f[x]=max(f[ls],f[rs]);
}
int query(int x,int l,int r,int ll,int rr){
if (ll<=l && r<=rr){
return f[x];
}
if (r<ll || l>rr) return 0;
pushdown(x);
int sum=0;
if (mid<rr) sum=max(sum,query(rs,mid+1,r,ll,rr));
if (mid>=ll) sum=max(sum,query(ls,l,mid,ll,rr));
f[x]=max(f[ls],f[rs]);
return sum;
}
int main(){
memset(la1,-0x3f,sizeof(la1));
ios::sync_with_stdio(false);
int n,q;cin>>n>>q;
for (int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while (q--){
int op;cin>>op;
if (op==1){
int l,r,x;cin>>l>>r>>x;
update(1,1,n,l,r,x);
}
if (op==2){
int l,r,x;cin>>l>>r>>x;
add(1,1,n,l,r,x);
}
if (op==3){
int l,r;cin>>l>>r;
cout<<query(1,1,n,l,r)<<'\n';
}
}
return 0;
}