const int MAXN=1e6+5,Inf=2e9;
int a[MAXN];
int lef[MAXN<<2],rig[MAXN<<2],maxv[MAXN<<2],mmaxv[MAXN<<2],maxc[MAXN<<2],secv[MAXN<<2];
int lazy1[MAXN<<2],lazy2[MAXN<<2],mlazy1[MAXN<<2],mlazy2[MAXN<<2];
LL sum[MAXN<<2];
void push_up(int k){
sum[k]=sum[k<<1]+sum[k<<1|1];
mmaxv[k]=max(mmaxv[k<<1],mmaxv[k<<1|1]);
if(maxv[k<<1]==maxv[k<<1|1]){
maxv[k]=maxv[k<<1];
maxc[k]=maxc[k<<1]+maxc[k<<1|1];
secv[k]=max(secv[k<<1],secv[k<<1|1]);
}
else if(maxv[k<<1]>maxv[k<<1|1]){
maxv[k]=maxv[k<<1];
maxc[k]=maxc[k<<1];
secv[k]=max(secv[k<<1],maxv[k<<1|1]);
}
else{
maxv[k]=maxv[k<<1|1];
maxc[k]=maxc[k<<1|1];
secv[k]=max(maxv[k<<1],secv[k<<1|1]);
}
}
void push_tag(int k,int v1,int v2,int mv1,int mv2){
sum[k]+=1LL*maxc[k]*v1+1LL*(rig[k]-lef[k]+1-maxc[k])*v2;
mmaxv[k]=max(mmaxv[k],maxv[k]+mv1);
mlazy1[k]=max(mlazy1[k],lazy1[k]+mv1);
maxv[k]+=v1,lazy1[k]+=v1;
mlazy2[k]=max(mlazy2[k],lazy2[k]+mv2);
if(secv[k]!=-Inf)secv[k]+=v2;
lazy2[k]+=v2;
}
void push_down(int k){
int temp=max(maxv[k<<1],maxv[k<<1|1]);
if(temp==maxv[k<<1])
push_tag(k<<1,lazy1[k],lazy2[k],mlazy1[k],mlazy2[k]);
else
push_tag(k<<1,lazy2[k],lazy2[k],mlazy2[k],mlazy2[k]);
if(temp==maxv[k<<1|1])
push_tag(k<<1|1,lazy1[k],lazy2[k],mlazy1[k],mlazy2[k]);
else
push_tag(k<<1|1,lazy2[k],lazy2[k],mlazy2[k],mlazy2[k]);
lazy1[k]=lazy2[k]=mlazy1[k]=mlazy2[k]=0;
}
void build(int k,int L,int R){
lef[k]=L,rig[k]=R,lazy1[k]=lazy2[k]=mlazy1[k]=mlazy2[k]=0;
int M=L+R>>1;
if(L==R){
sum[k]=maxv[k]=mmaxv[k]=a[M];
secv[k]=-Inf;
maxc[k]=1;
return;
}
build(k<<1,L,M);
build(k<<1|1,M+1,R);
push_up(k);
}
void update_add(int k,int L,int R,int v){
if(L<=lef[k]&&rig[k]<=R)
return push_tag(k,v,v,v,v);
push_down(k);
int mid=lef[k]+rig[k]>>1;
if(mid>=L)update_add(k<<1,L,R,v);
if(mid<R)update_add(k<<1|1,L,R,v);
push_up(k);
}
void update_min(int k,int L,int R,int v){
if(maxv[k]<=v)return;
if(L<=lef[k]&&rig[k]<=R&&secv[k]<v)
return push_tag(k,v-maxv[k],0,v-maxv[k],0);
push_down(k);
int mid=lef[k]+rig[k]>>1;
if(mid>=L)update_min(k<<1,L,R,v);
if(mid<R)update_min(k<<1|1,L,R,v);
push_up(k);
}
LL query_sum(int k,int L,int R){
if(L<=lef[k]&&rig[k]<=R)return sum[k];
push_down(k);
int mid=lef[k]+rig[k]>>1;
LL s=0;
if(mid>=L)s+=query_sum(k<<1,L,R);
if(mid<R)s+=query_sum(k<<1|1,L,R);
return s;
}
int query_max(int k,int L,int R){
if(L<=lef[k]&&rig[k]<=R)return maxv[k];
push_down(k);
int mid=lef[k]+rig[k]>>1,vl=-Inf,vr=-Inf;
if(mid>=L)vl=query_max(k<<1,L,R);
if(mid<R)vr=query_max(k<<1|1,L,R);
return max(vl,vr);
}
int query_mmax(int k,int L,int R){
if(L<=lef[k]&&rig[k]<=R)return mmaxv[k];
push_down(k);
int mid=lef[k]+rig[k]>>1,vl=-Inf,vr=-Inf;
if(mid>=L)vl=query_mmax(k<<1,L,R);
if(mid<R)vr=query_mmax(k<<1|1,L,R);
return max(vl,vr);
}
int main()
{
int n=read_int(),q=read_int();
_rep(i,1,n)a[i]=read_int();
build(1,1,n);
while(q--){
int opt=read_int(),l=read_int(),r=read_int();
switch(opt){
case 1:
update_add(1,l,r,read_int());
break;
case 2:
update_min(1,l,r,read_int());
break;
case 3:
enter(query_sum(1,l,r));
break;
case 4:
enter(query_max(1,l,r));
break;
case 5:
enter(query_mmax(1,l,r));
break;
}
}
return 0;
}