#include<algorithm>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const ll N=1e6,inf=1e12;
ll n,m,a[N],mx[4*N],tagsum[4*N],tagmax[4*N];
void build(ll p,ll l,ll r) {
if(l==r) {
mx[p]=a[l];
return ;
}
ll mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tagmax[p]=-inf;
mx[p]=max(mx[p*2],mx[p*2+1]);
}
void add(ll p,ll l,ll r,ll v) {
if(tagmax[p]!=-inf) tagmax[p]+=v;
tagsum[p]+=v;
mx[p]+=v;
}
void maxi(ll p,ll l,ll r,ll v) {
mx[p]=tagmax[p]=v;
tagsum[p]=0;
}
void pushdown(ll p,ll l,ll r) {
ll mid=(l+r)/2;
if(tagmax[p]!=-inf) {
maxi(p*2,l,mid,tagmax[p]);
maxi(p*2+1,mid+1,r,tagmax[p]);
}
add(p*2,l,mid,tagsum[p]);
add(p*2+1,mid+1,r,tagsum[p]);
tagmax[p]=-inf;
tagsum[p]=0;
}
void modifysum(ll p,ll l,ll r,ll x,ll y,ll v) {
if(x<=l&&r<=y) {
add(p,l,r,v);
return ;
}
pushdown(p,l,r);
ll mid=(l+r)/2;
if(x<=mid) modifysum(p*2,l,mid,x,y,v);
if(y>mid) modifysum(p*2+1,mid+1,r,x,y,v);
mx[p]=max(mx[p*2],mx[p*2+1]);
}
void modifymax(ll p,ll l,ll r,ll x,ll y,ll v) {
if(x<=l&&r<=y) {
maxi(p,l,r,v);
return ;
}
pushdown(p,l,r);
ll mid=(l+r)/2;
if(x<=mid) modifymax(p*2,l,mid,x,y,v);
if(y>mid) modifymax(p*2+1,mid+1,r,x,y,v);
mx[p]=max(mx[p*2],mx[p*2+1]);
}
ll query(ll p,ll l,ll r,ll x,ll y) {
if(x<=l&&r<=y) return mx[p];
pushdown(p,l,r);
ll mid=(l+r)/2,res=-inf;
if(x<=mid) res=max(res,query(p*2,l,mid,x,y));
if(y>mid) res=max(res,query(p*2+1,mid+1,r,x,y));
return res;
}
signed main() {
scanf("%lld %lld",&n,&m);
for(ll i=1; i<=n; i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(; m; m--) {
ll x,y,k,opt;
scanf("%lld %lld %lld",&opt,&x,&y);
if(opt==1) {
scanf("%lld",&k);
modifymax(1,1,n,x,y,k);
} else if(opt==2) {
scanf("%lld",&k);
modifysum(1,1,n,x,y,k);
} else {
printf("%lld\n",query(1,1,n,x,y));
}
}
return 0;
}