#include<bits/stdc++.h>
#define LL long long
#define maxn 1000005
using namespace std;
LL n;
LL a[maxn],w[maxn*4],tag1[maxn*4],tag2[maxn*4];
void pushup(LL u){
w[u]=max(w[u*2],w[u*2+1]);
}
void build(LL u,LL L,LL R){
if(L==R){
w[u]=a[L];
return;
}
LL M=(L+R)/2;
build(u*2,L,M);
build(u*2+1,M+1,R);
pushup(u);
}
void pushdown(LL u){
if(tag1[u]){
tag1[u*2]=tag1[u];
tag1[u*2+1]=tag1[u];
w[u*2]=tag1[u];
w[u*2+1]=tag1[u];
}
if(tag2[u]){
tag2[u*2]+=tag2[u];
tag2[u*2+1]+=tag2[u];
w[u*2]+=tag2[u];
w[u*2+1]+=tag2[u];
}
tag1[u]=tag2[u]=0;
}
void change(LL u,LL L,LL R,LL l,LL r,LL x){
if(l<=L&&R<=r){
tag2[u]=0;
tag1[u]=x;
w[u]=x;
return;
}
pushdown(u);
LL M=(L+R)/2;
if(l<=M) change(u*2,L,M,l,r,x);
if(r>M) change(u*2+1,M+1,R,l,r,x);
pushup(u);
}
void update(LL u,LL L,LL R,LL l,LL r,LL x){
if(l<=L&&R<=r){
tag2[u]+=x;
w[u]+=x;
return;
}
pushdown(u);
LL M=(L+R)/2;
if(l<=M) update(u*2,L,M,l,r,x);
if(r>M) update(u*2+1,M+1,R,l,r,x);
pushup(u);
}
LL query(LL u,LL L,LL R,LL l,LL r){
if(l<=L&&R<=r){
return w[u];
}
pushdown(u);
LL M=(L+R)/2;
const LL undif=-20250130;
LL a=undif,b=undif;
if(l<=M) a=query(u*2,L,M,l,r);
if(r>M) b=query(u*2+1,M+1,R,l,r);
if(a==undif) return b;
if(b==undif) return a;
return max(a,b);
}
int main(){
LL n,q;
cin>>n>>q;
for(LL i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(q--){
LL opt,x,y,z;
cin>>opt>>x>>y;
if(opt==1){
cin>>z;
change(1,1,n,x,y,z);
}
if(opt==2){
cin>>z;
update(1,1,n,x,y,z);
}
if(opt==3){
cout<<query(1,1,n,x,y)<<"\n";
}
}
return 0;
}