#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,q;
long long a[N];
struct node{
long long l,r,v,tag,tag1;
bool f;
}tri[N*4];
int qread(){
int ret=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=ret*10+ch-'0';
ch=getchar();
}
return ret*f;
}
void build(int p,int l,int r){
tri[p].l=l;
tri[p].r=r;
tri[p].f=0;
if(l==r){
tri[p].v=a[l];
return;
}
int mid=l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tri[p].v=max(tri[p*2].v,tri[p*2+1].v);
}
void update1(int p,int l,int r,int k){
if(tri[p].l>=l&&tri[p].r<=r){
tri[p].tag=0;
tri[p].tag1=k;
tri[p].f=1;
tri[p].v=k;
return;
}
if(tri[p].f==1){
tri[p*2].v=tri[p].tag1;
tri[p*2+1].v=tri[p].tag1;
tri[p*2].tag1=tri[p].tag1;
tri[p*2+1].tag1=tri[p].tag1;
tri[p*2+1].tag=0;
tri[p*2].tag=0;
tri[p*2].f=1;
tri[p*2+1].f=1;
tri[p].f=0;
}
tri[p*2].tag+=tri[p].tag;
tri[p*2+1].tag+=tri[p].tag;
tri[p*2].v+=tri[p].tag;
tri[p*2+1].v+=tri[p].tag;
tri[p].tag=0;
int mid=tri[p].l+tri[p].r>>1;
if(l<=mid)update1(p*2,l,r,k);
if(r>mid)update1(p*2+1,l,r,k);
tri[p].v=max(tri[p*2].v,tri[p*2+1].v);
}
void update2(int p,int l,int r,int k){
if(tri[p].l>=l&&tri[p].r<=r){
tri[p].tag+=k;
tri[p].v+=k;
return;
}
if(tri[p].f==1){
tri[p*2].v=tri[p].tag1;
tri[p*2+1].v=tri[p].tag1;
tri[p*2].tag1=tri[p].tag1;
tri[p*2+1].tag1=tri[p].tag1;
tri[p*2].tag=0;
tri[p*2+1].tag=0;
tri[p*2].f=1;
tri[p*2+1].f=1;
tri[p].f=0;
}
tri[p*2].tag+=tri[p].tag;
tri[p*2+1].tag+=tri[p].tag;
tri[p*2].v+=tri[p].tag;
tri[p*2+1].v+=tri[p].tag;
tri[p].tag=0;
int mid=tri[p].l+tri[p].r>>1;
if(l<=mid)update2(p*2,l,r,k);
if(r>mid)update2(p*2+1,l,r,k);
tri[p].v=max(tri[p*2].v,tri[p*2+1].v);
}
long long query(int p,int l,int r){
if(tri[p].l>=l&&tri[p].r<=r){
return tri[p].v;
}
if(tri[p].f==1){
tri[p*2].v=tri[p*2+1].v=tri[p].tag1;
tri[p*2].tag1=tri[p*2+1].tag1=tri[p].tag1;
tri[p].f=0;
tri[p*2].f=1;
tri[p*2+1].f=1;
}
tri[p*2].tag+=tri[p].tag;
tri[p*2+1].tag+=tri[p].tag;
tri[p*2].v+=tri[p].tag;
tri[p*2+1].v+=tri[p].tag;
tri[p].tag=0;
long long ret=-1e18;
int mid=tri[p].l+tri[p].r>>1;
if(l<=mid)ret=max(ret,query(p*2,l,r));
if(r>mid)ret=max(ret,query(p*2+1,l,r));
tri[p].v=max(tri[p*2].v,tri[p*2+1].v);
return ret;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
a[i]=qread();
}
build(1,1,n);
for(int op,l,r,x,i=1;i<=q;i++){
op=qread();
if(op==1){
l=qread();
r=qread();
x=qread();
update1(1,l,r,x);
}
if(op==2){
l=qread();
r=qread();
x=qread();
update2(1,l,r,x);
}
if(op==3){
l=qread();
r=qread();
cout<<query(1,l,r)<<endl;
}
}
return 0;
}