#include <bits/stdc++.h>
#define int long long
#define MAXN 1000005
#define none -114514
using namespace std;
int n,q,a[MAXN];
struct SegmentTree{
int l,r,len,maxx;
int add,to;
}t[MAXN*4];
void pushup(int x){
t[x].maxx=max(t[x*2].maxx,t[x*2+1].maxx);
}
void build(int x,int l,int r){
t[x].l=l,t[x].r=r,t[x].len=r-l+1,t[x].to=none;
if(l==r){
t[x].maxx=a[x];
return ;
}
int mid=(l+r)>>1;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
pushup(x);
}
void cpushdown(int x){
if(t[x].to!=none){
//printf("%lld\n",t[x].to);
t[x*2].add=t[x*2+1].add=0;
t[x*2].maxx=t[x*2+1].maxx=t[x].to;
t[x*2].to=t[x*2+1].to=t[x].to;
t[x].to=none;
}
}
void apushdown(int x){
if(t[x].add){
cpushdown(x);
t[x*2].maxx+=t[x].add;
t[x*2+1].maxx+=t[x].add;
t[x*2].add+=t[x].add;
t[x*2+1].add+=t[x].add;
t[x].add=0;
}
}
void pushdown(int x){
cpushdown(x);
apushdown(x);
}
int query(int x,int l,int r){
int L=t[x].l,R=t[x].r;
if(L>=l&&R<=r)return t[x].maxx;
int mid=(L+R)>>1,val=0;
pushdown(x);
if(l<=mid)val=max(val,query(x*2,l,r));
if(r>mid)val=max(val,query(x*2+1,l,r));
return val;
}
void changeto(int x,int l,int r,int k){
int L=t[x].l,R=t[x].r;
if(L>=l&&R<=r){
t[x].add=0;
t[x].maxx=k;
t[x].to=k;
return ;
}
pushdown(x);
int mid=(L+R)>>1;
if(l<=mid)changeto(x*2,l,r,k);
if(r>mid)changeto(x*2+1,l,r,k);
pushup(x);
}
void changeadd(int x,int l,int r,int k){
int L=t[x].l,R=t[x].r;
if(L>=l&&R<=r){
cpushdown(x);
t[x].maxx+=k;
t[x].add+=k;
return ;
}
pushdown(x);
int mid=(L+R)>>1;
if(l<=mid)changeadd(x*2,l,r,k);
if(r>mid)changeadd(x*2+1,l,r,k);
pushup(x);
}
signed main(){
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
build(1,1,n);
while(q--){
int op;
scanf("%lld",&op);
if(op==1){
int l,r,x;
scanf("%lld%lld%lld",&l,&r,&x);
changeto(1,l,r,x);
}
if(op==2){
int l,r,x;
scanf("%lld%lld%lld",&l,&r,&x);
changeadd(1,l,r,x);
}
if(op==3){
int l,r;
scanf("%lld%lld",&l,&r);
printf("%lld\n",query(1,l,r));
}
}
return 0;
}
谢谢!