//By lzj
#include <cstdio>
#define ri register int
#define ls p<<1
#define rs p<<1|1
#define int long long
#define INF 1e15
using namespace std;
const int N=1e6+15;
struct node{
int l,r;
int tag1,tag2;
int sum,maxn,minn;
}tree[N<<2];
inline int read(){
int f=1; int num=0;
char ch=getchar();
while(ch<'0'||ch>'9'){f|=(ch=='-'?-1:1);ch=getchar();}
while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+(ch^48); ch=getchar();}
return num*f;
}
void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a<b?a:b;
}
int n,q,op,x,y,z;
int a[N];
void pushup(int p){
tree[p].sum=tree[ls].sum+tree[rs].sum;
tree[p].maxn=max(tree[ls].maxn,tree[rs].maxn);
tree[p].minn=min(tree[ls].minn,tree[rs].minn);
}
void pushdown(int p){
if(tree[p].tag1!=-INF){
tree[ls].tag1=tree[rs].tag1=tree[p].tag1;
tree[ls].maxn=tree[p].tag1;
tree[rs].maxn=tree[p].tag1;
tree[ls].minn=tree[p].tag1;
tree[rs].minn=tree[p].tag1;
tree[ls].sum=tree[p].tag1*(tree[ls].r-tree[ls].l+1);
tree[rs].sum=tree[p].tag1*(tree[rs].r-tree[rs].l+1);
tree[ls].tag2=tree[rs].tag2=0;
tree[p].tag1=-INF;
}
if(tree[p].tag2){
tree[ls].tag2+=tree[p].tag2;
tree[rs].tag2+=tree[p].tag2;
tree[ls].maxn+=tree[p].tag2;
tree[rs].maxn+=tree[p].tag2;
tree[ls].minn+=tree[p].tag2;
tree[rs].minn+=tree[p].tag2;
tree[ls].sum+=tree[p].tag2*(tree[ls].r-tree[ls].l+1);
tree[rs].sum+=tree[p].tag2*(tree[rs].r-tree[rs].l+1);
tree[p].tag2=0;
}
}
void build(int p,int l,int r){
tree[p].l=l;tree[p].r=r; tree[p].tag1=-INF;tree[p].tag2=0;
if(l==r){
tree[p].sum=tree[p].minn=tree[p].maxn=a[l]; return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
void update1(int p,int l,int r,int delta){
if(l<=tree[p].l&&tree[p].r<=r){
tree[p].sum=delta*(tree[p].r-tree[p].l+1);
tree[p].maxn=tree[p].minn=delta;
tree[p].tag1=delta;
tree[p].tag2=0;
return;
}
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid) update1(ls,l,r,delta);
if(r>mid) update1(rs,l,r,delta);
pushup(p);
}
void update2(int p,int l,int r,int delta){
if(l<=tree[p].l&&tree[p].r<=r){
tree[p].maxn+=delta;
tree[p].minn+=delta;
tree[p].sum+=(tree[p].r-tree[p].l+1)*delta;
tree[p].tag2+=delta;
return;
}
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1;
if(l<=mid) update2(ls,l,r,delta);
if(r>mid) update2(rs,l,r,delta);
pushup(p);
}
int qmax(int p,int l,int r){
if(l<=tree[p].l&&tree[p].r<=r){
return tree[p].maxn;
}
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1,val=-INF;
if(l<=mid) val=max(val,qmax(ls,l,r));
if(r>mid) val=max(val,qmax(rs,l,r));
return val;
}
int qmin(int p,int l,int r){
if(l<=tree[p].l&&tree[p].r<=r){
return tree[p].minn;
}
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1,val=INF;
if(l<=mid) val=min(val,qmin(ls,l,r));
if(r>mid) val=min(val,qmin(rs,l,r));
return val;
}
int query(int p,int l,int r){
if(l<=tree[p].l&&tree[p].r<=r){
return tree[p].sum;
}
pushdown(p);
int mid=(tree[p].l+tree[p].r)>>1,val=0;
if(l<=mid) val+=query(ls,l,r);
if(r>mid) val+=query(rs,l,r);
return val;
}
signed main(){
n=read(); q=read();
for(ri i=1;i<=n;i++) a[i]=read();
build(1,1,n);
while(q--){
op=read();
if(op==1){
x=read(); y=read(); z=read();
update1(1,x,y,z);
}
if(op==2){
x=read(); y=read(); z=read();
update2(1,x,y,z);
}
if(op==3){
x=read(); y=read();
write(qmax(1,x,y));
putchar('\n');
}
if(op==4){
x=read(); y=read();
write(qmin(1,x,y));
putchar('\n');
}
if(op==5){
x=read(); y=read();
write(query(1,x,y));
putchar('\n');
}
}
return 0;
}