const int MAXN=1e6+5,Inf=2e9;
int a[MAXN];
int lef[MAXN<<2],rig[MAXN<<2],maxv[MAXN<<2],maxc[MAXN<<2],secv[MAXN<<2];
int lazy1[MAXN<<2],lazy2[MAXN<<2];
LL sum[MAXN<<2];
void push_up(int k){
sum[k]=sum[k<<1]+sum[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_add(int k,int v){
sum[k]+=1LL*(rig[k]-lef[k]+1)*v;
maxv[k]+=v,lazy1[k]+=v;
if(secv[k]!=-Inf)secv[k]+=v;
if(lazy2[k]!=-Inf)lazy2[k]+=v;
}
void push_min(int k,int v){
if(v>=maxv[k])return;
sum[k]-=1LL*maxc[k]*(maxv[k]-v);
maxv[k]=lazy2[k]=v;
}
void push_down(int k){
if(lazy1[k]){
push_add(k<<1,lazy1[k]);
push_add(k<<1|1,lazy1[k]);
lazy1[k]=0;
}
if(lazy2[k]!=-Inf){
push_min(k<<1,lazy2[k]);
push_min(k<<1|1,lazy2[k]);
lazy2[k]=-Inf;
}
}
void build(int k,int L,int R){
lef[k]=L,rig[k]=R,lazy1[k]=0,lazy2[k]=-Inf;
int M=L+R>>1;
if(L==R){
sum[k]=maxv[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_add(k,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_min(k,v);
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 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;
}
}
return 0;
}