#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e7+10;
const ll INF=9223372036854775800;
int n,m;
ll a[N],add[N],cha[N],maxx[N];
bool flag[N];
ll read(){
ll w=1,s=0;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
return s*w;
}
void build(int k,int l,int r){
if(l==r){maxx[k]=a[l];return ;}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
maxx[k]=max(maxx[k*2],maxx[k*2+1]);
cha[k]=INF;
}
void All(int k,int v){
cha[k]=v;
add[k]=0;
maxx[k]=v;
}
void Add(int k,int v){
if(cha[k]!=INF){
cha[k]+=v;
add[k]=0;
}
else add[k]+=v;
maxx[k]+=v;
}
void push_down(int k,int l,int r,int mid){
if(cha[k]!=INF){
All(k*2,cha[k]);
All(k*2+1,cha[k]);
cha[k]=INF;
}
else if(add[k]!=0){
Add(k*2,add[k]);
Add(k*2+1,add[k]);
add[k]=0;
}
}
ll query(int k,int l,int r,int x,int y){
if(x<=l&&r<=y) return maxx[k];
int mid=(l+r)/2;
push_down(k,l,r,mid);
ll res=-INF;
if(x<=mid) res=max(res,query(k*2,l,mid,x,y));
if(mid<y) res=max(query(k*2+1,mid+1,r,x,y),res);
return res;
}
void change_add(int k,int l,int r,int x,int y,int v){
if(x<=l&&r<=y){Add(k,v);return ;}
int mid=(l+r)/2;
push_down(k,l,r,mid);
if(x<=mid) change_add(k*2,l,mid,x,y,v);
if(mid<y) change_add(k*2+1,mid+1,r,x,y,v);
maxx[k]=max(maxx[k*2],maxx[k*2+1]);
}
void change_all(int k,int l,int r,int x,int y,int v){
if(x<=l&&r<=y){All(k,v);return ;}
int mid=(l+r)/2;
push_down(k,l,r,mid);
if(x<=mid) change_all(k*2,l,mid,x,y,v);
if(mid<y) change_all(k*2+1,mid+1,r,x,y,v);
maxx[k]=max(maxx[k*2],maxx[k*2+1]);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
ll opt,l,r,x;
for(int i=1;i<=m;i++){
opt=read();l=read();r=read();
if(opt==3){
printf("%lld\n",query(1,1,n,l,r));
}
else if(opt==1){
x=read();
change_all(1,1,n,l,r,x);
}
else{
x=read();
change_add(1,1,n,l,r,x);
}
}
return 0;
}