#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,INF=-9223372036854775805;
int n,m,a[N];
struct Segment_Tree{
int l,r,add,Max,cov;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define add(x) tr[x].add
#define Max(x) tr[x].Max
#define cov(x) tr[x].cov
}tr[N*4];
void push_up(int p){
Max(p)=max(Max(p*2),Max(p*2+1));
}
void build(int p,int l,int r){
l(p)=l,r(p)=r;
if(l==r){
Max(p)=a[l];
cov(p)=INF;
return;
}
int mid=l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
push_up(p);
}
void spread_cov(int p){
if(cov(p)!=0){
add(p*2)=add(p*2+1)=add(p)=0;
cov(p*2)=cov(p*2+1)=cov(p);
Max(p*2)=cov(p*2),Max(p*2+1)=cov(p*2);
cov(p)=0;
}
}
void spread(int p){
if(add(p)){
spread_cov(p);
add(p*2)+=add(p);
add(p*2+1)+=add(p);
Max(p*2)+=add(p);
Max(p*2+1)+=add(p);
add(p)=0;
}
}
void cg(int p,int l,int r,int d){
if(l<=l(p) && r(p)<=r){
spread_cov(p);
Max(p)+=d;
add(p)+=d;
return;
}
spread_cov(p),spread(p);
int mid=l(p)+r(p)>>1;
if(l<=mid) cg(p*2,l,r,d);
if(r>mid) cg(p*2+1,l,r,d);
push_up(p);
}
void cg2(int p,int l,int r,int d){
if(l<=l(p) && r(p)<=r){
Max(p)=d;
return;
}
spread_cov(p),spread(p);
int mid=l(p)+r(p)>>1;
if(l<=mid) cg2(p*2,l,r,d);
if(r>mid) cg2(p*2+1,l,r,d);
push_up(p);
}
int ask(int p,int l,int r){
if(l<=l(p) && r(p)<=r){
return Max(p);
}
spread_cov(p),spread(p);
int val=INF;
int mid=(l(p)+r(p))>>1;
if(l<=mid) val=max(ask(p*2,l,r),val);
if(r>mid) val=max(ask(p*2+1,l,r),val);
return val;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
int op;
cin>>op;
if(op==1){
int l,r,d;
cin>>l>>r>>d;
cg2(1,l,r,d);
}
if(op==2){
int l,r,d;
cin>>l>>r>>d;
cg(1,l,r,d);
}
if(op==3){
int l,r;
cin>>l>>r;
cout<<ask(1,l,r)<<endl;
}
}
}