#include<bits/stdc++.h>
using namespace std;
#define int long long
#define y1 Y1
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define P pair<int,int>
#define x first
#define y second
#define modd(x) (((x)%mod+mod)%mod)
#define rd read()
#define lowbit(x) ((x)&(-x))
#define abs(x) ((x)<0?-(x):(x))
#define lc now<<1
#define rc now<<1|1
mt19937 rnd(time(0));
inline int read(int u=0, char c=getchar(), bool f=false){
for (;!isdigit(c);c=getchar()) f|=c=='-';
for (;isdigit(c);c=getchar()) u=(u<<1)+(u<<3)+c-'0';
return f?-u:u;
}
inline void wt(int x){
if(x<0) x=-x,putchar('-');
if(x>9) wt(x/10);
putchar(x%10+48);
}
inline void wt(int x,char k){wt(x),putchar(k);}
const int inf=~0U>>1,linf=~0ULL>>1;
const int mod=998244353;
const int N=5e5+10;
struct node{
int l,r,maxx,add,minadd,maxadd;
};
struct tree{
node tr[N<<2];
void pushup(int now){tr[now].maxx=max(tr[lc].maxx,tr[rc].maxx);}
void pushdown_sum(int now,int x){
tr[now].maxx+=x;
tr[now].add+=x;
if(tr[now].maxadd>-inf) tr[now].maxadd+=x;
if(tr[now].minadd<inf) tr[now].minadd+=x;
}
void pushdown_max(int now,int x){
tr[now].maxx=max(tr[now].maxx,x);
tr[now].maxadd=max(tr[now].maxadd,x);
tr[now].minadd=max(tr[now].minadd,x);
}
void pushdown_min(int now,int x){
tr[now].maxx=min(tr[now].maxx,x);
tr[now].maxadd=min(tr[now].maxadd,x);
tr[now].minadd=min(tr[now].minadd,x);
}
void pushdown(int now){
pushdown_sum(lc,tr[now].add),pushdown_sum(rc,tr[now].add);
pushdown_min(lc,tr[now].minadd),pushdown_min(rc,tr[now].minadd);
pushdown_max(lc,tr[now].maxadd),pushdown_max(rc,tr[now].maxadd);
tr[now].add=0,tr[now].maxadd=-inf,tr[now].minadd=inf;
}
void build(int now,int l,int r){
tr[now]={l,r,-inf,0,inf,-inf};
if(l==r){
tr[now].maxx=rd;
return ;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(now);
}
void modify_sum(int now,int l,int r,int x){
if(l<=tr[now].l&&tr[now].r<=r){
pushdown_sum(now,x);
return ;
}
int mid=tr[now].l+tr[now].r>>1;
pushdown(now);
if(l<=mid) modify_sum(lc,l,r,x);
if(r>mid) modify_sum(rc,l,r,x);
pushup(now);
}
void modify_max(int now,int l,int r,int x){
if(l<=tr[now].l&&tr[now].r<=r){
pushdown_max(now,x);
return ;
}
int mid=tr[now].l+tr[now].r>>1;
pushdown(now);
if(l<=mid) modify_max(lc,l,r,x);
if(r>mid) modify_max(rc,l,r,x);
pushup(now);
}
void modify_min(int now,int l,int r,int x){
if(l<=tr[now].l&&tr[now].r<=r){
pushdown_min(now,x);
return ;
}
int mid=tr[now].l+tr[now].r>>1;
pushdown(now);
if(l<=mid) modify_min(lc,l,r,x);
if(r>mid) modify_min(rc,l,r,x);
pushup(now);
}
int query(int now,int l,int r){
if(l<=tr[now].l&&tr[now].r<=r) return tr[now].maxx;
int mid=tr[now].l+tr[now].r>>1,ans=-inf;
pushdown(now);
if(l<=mid) ans=max(ans,query(lc,l,r));
if(r>mid) ans=max(ans,query(rc,l,r));
return ans;
}
}T;
int n,q;
main(){
n=rd,q=rd;
T.build(1,1,n);
while(q--){
int op=rd,l=rd,r=rd,x;
if(op!=4) x=rd;
if(op==1) T.modify_sum(1,l,r,x);
if(op==2) T.modify_min(1,l,r,x);
if(op==3) T.modify_max(1,l,r,x);
if(op==4) wt(T.query(1,l,r),'\n');
}
return 0;
}