#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
#define complete t[i].l>=l&&t[i].r<=r
struct node{
int l,r;
long long maxn,covertag,addtag;
bool covered;
}t[MAXN*4];
int n,m,a[MAXN];
inline void build(int i,int l,int r){
t[i].l=l;
t[i].r=r;
t[i].addtag=0;
t[i].covered=false;
if(l==r){
t[i].maxn=a[l];
return ;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
t[i].maxn=max(t[i<<1].maxn,t[i<<1|1].maxn);
}
inline void pushdown(int i){
if(t[i].covered){
t[i<<1].maxn=t[i].covertag;
t[i<<1|1].maxn=t[i].covertag;
t[i<<1].covered=t[i<<1|1].covered=true;
t[i<<1].covertag=t[i<<1|1].covertag=t[i].covertag;
t[i].covered=false;
}
t[i<<1].maxn+=t[i].addtag;
t[i<<1|1].maxn+=t[i].addtag;
t[i<<1].addtag+=t[i].addtag;
t[i<<1|1].addtag+=t[i].addtag;
t[i].addtag=0;
}
inline void add(int i,int l,int r,long long k){
if(complete){
t[i].addtag+=k;
t[i].maxn+=k;
return ;
}
pushdown(i);
if(t[i<<1].r>=l) add(i<<1,l,r,k);
if(t[i<<1|1].l<=r) add(i<<1|1,l,r,k);
t[i].maxn=max(t[i<<1].maxn,t[i<<1|1].maxn);
}
inline void cover(int i,int l,int r,long long k){
if(complete){
t[i].covered=true;
t[i].covertag=k;
t[i].addtag=0;
t[i].maxn=k;
return ;
}
pushdown(i);
if(t[i<<1].r>=l) cover(i<<1,l,r,k);
if(t[i<<1|1].l<=r) cover(i<<1|1,l,r,k);
t[i].maxn=max(t[i<<1].maxn,t[i<<1|1].maxn);
}
inline long long search(int i,int l,int r){
if(complete) return t[i].maxn;
pushdown(i);
long long s=-LONG_LONG_MAX;
if(t[i<<1].r>=l) s=max(s,search(i<<1,l,r));
if(t[i<<1|1].l<=r) s=max(s,search(i<<1|1,l,r));
return s;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
while(m--){
int op,l,r;
long long x;
scanf("%d%d%d",&op,&l,&r);
if(op==3){
printf("%lld\n",search(1,l,r));
}
else{
scanf("%lld",&x);
if(op==1) cover(1,l,r,x);
else add(1,l,r,x);
}
}
return 0;
}