#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const ll Inf=-1145141919810;
ll ans,n,q,d[maxn<<1],lc[maxn<<1],rc[maxn<<1],a[maxn],root,num,cover[maxn<<1],add[maxn<<1];
void get_sum(ll rt){
d[rt]=max(d[lc[rt]],d[rc[rt]]);
}
void build(ll s,ll t,ll &p){
if(!p) p=++num;
if(s==t){
d[p]=a[s];
cover[p]=Inf;
return;
}
ll mid=s+t>>1;
build(s,mid,lc[p]);
build(mid+1,t,rc[p]);
get_sum(p);
}
void coverdown(ll s,ll t,ll p){
if(cover[p]!=Inf){
add[lc[p]]=add[rc[p]]=0;
cover[lc[p]]=cover[rc[p]]=cover[p];
d[lc[p]]=d[rc[p]]=cover[p];
cover[p]=Inf;
}
}
void adddown(ll s,ll t,ll p){
if(add[p]){
add[lc[p]]+=add[p];
add[rc[p]]+=add[p];
d[lc[p]]+=add[p];
d[rc[p]]+=add[p];
add[p]=0;
}
}
void Pushdown(ll s,ll t,ll p){
coverdown(s,t,p);
adddown(s,t,p);
}
void update1(ll s,ll t,ll &p,ll l,ll r,ll k){
if(!p) p=++num;
if(l<=s && r>=t){
d[p]=k;
cover[p]=k;
add[p]=0;
return;
}
Pushdown(s,t,p);
ll mid=s+t>>1;
if(l<=mid) update1(s,mid,lc[p],l,r,k);
if(r>mid) update1(mid+1,t,rc[p],l,r,k);
get_sum(p);
}
void update2(ll s,ll t,ll &p,ll l,ll r,ll k){
if(!p) p=++num;
if(l<=s && r>=t){
coverdown(s,t,p);
d[p]+=k;
add[p]+=k;
return;
}
Pushdown(s,t,p);
ll mid=s+t>>1;
if(l<=mid) update2(s,mid,lc[p],l,r,k);
if(r>mid) update2(mid+1,t,rc[p],l,r,k);
get_sum(p);
}
ll query(ll s,ll t,ll p,ll l,ll r){
if(!p) return -Inf;
if(l<=s && r>=t) return d[p];
Pushdown(s,t,p);
get_sum(p);
ll mid=s+t>>1,tot=Inf;
if(l<=mid) tot=max(tot,query(s,mid,lc[p],l,r));
if(r>mid) tot=max(tot,query(mid+1,t,rc[p],l,r));
return tot;
}
int main(){
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=2*n;i++) cover[i]=Inf;
build(1,n,root);
for(int i=1;i<=q;i++){
int op;
scanf("%d",&op);
if(op==1){
ll l,r,x;
scanf("%lld%lld%lld",&l,&r,&x);
update1(1,n,root,l,r,x);
}else if(op==2){
ll l,r,k;
scanf("%lld%lld%lld",&l,&r,&k);
update2(1,n,root,l,r,k);
}else {
ll l,r;
scanf("%lld%lld",&l,&r);
ans=query(1,n,root,l,r);
printf("%lld\n",ans);
}
}
return 0;
}