#include<bits/stdc++.h>
#define int long long
using namespace std;
const int INF=1e18;
int n,q;
int t[4000005],add[4000005],tag[4000005];
int ls(int p){return p<<1;}
int rs(int p){return p<<1|1;}
void push_up(int p){t[p]=max(t[ls(p)],t[rs(p)]);}
void build(int p,int pl,int pr){
if(pl==pr){cin>>t[p];return ;}
int mid=pl+pr>>1;
build(ls(p),pl,mid);
build(rs(p),mid+1,pr);
push_up(p);
}
void push_down(int p){
if(tag[p]!=INF){
add[ls(p)]=add[rs(p)]=0;
t[ls(p)]=t[rs(p)]=tag[p];
tag[p]=INF;
}
if(add[p]){
add[ls(p)]+=add[p];add[rs(p)]+=add[p];
t[ls(p)]+=add[p];t[rs(p)]+=add[p];add[p]=0;
}
}
void update(int L,int R,int p,int pl,int pr,int X){
if(L<=pl&&pr<=R){
add[p]=0;t[p]=X;tag[p]=X;
return ;
}
push_down(p);
int mid=pl+pr>>1;
if(L<=mid)update(L,R,ls(p),pl,mid,X);
if(R>mid)update(L,R,rs(p),mid+1,pr,X);
push_up(p);
}
void addupdate(int L,int R,int p,int pl,int pr,int X){
if(L<=pl&&pr<=R){
add[p]+=X;t[p]+=X;
return ;
}
push_down(p);
int mid=pl+pr>>1;
if(L<=mid)addupdate(L,R,ls(p),pl,mid,X);
if(R>mid)addupdate(L,R,rs(p),mid+1,pr,X);
push_up(p);
}
int query(int L,int R,int p,int pl,int pr){
if(L<=pl&&pr<=R)return t[p];
push_down(p);
int mid=pl+pr>>1,res=-INF;
if(L<=mid)res=max(res,query(L,R,ls(p),pl,mid));
if(R>mid)res=max(res,query(L,R,rs(p),mid+1,pr));
return res;
}
signed main(){
freopen("1.txt","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>q;
for(int i=1;i<=4000005;i++)tag[i]=INF;
build(1,1,n);
while(q--){
int op,l,r,x;
cin>>op>>l>>r;
if(op==1)cin>>x,update(l,r,1,1,n,x);
else if(op==2)cin>>x,addupdate(l,r,1,1,n,x);
else cout<<query(l,r,1,1,n)<<'\n';
}
return 0;
}