原题
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,q,a[1000010],op,l,r,x;
struct node{
ll maxn,l,r;
ll lazy1,lazy2;
}tr[4*1000010];
inline ll read(){
ll x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
void build(ll root,ll L,ll R){
tr[root].l=L,tr[root].r=R;
if(L==R){tr[root].maxn=a[L],tr[root].lazy2=-1145141919810;return ;}
ll mid=(L+R)/2;
build(root*2,L,mid),build(root*2+1,mid+1,R);
tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);
}
void coverdown(ll root){
if(tr[root].lazy2!=-1145141919810){
tr[root*2].lazy1=tr[root*2+1].lazy1=0;
tr[root*2].maxn=tr[root*2+1].maxn=tr[root].lazy2;
tr[root*2].lazy2=tr[root*2+1].lazy2=tr[root].lazy2;
tr[root].lazy2=-1145141919810;
}
}
void sumdown(ll root){
if(tr[root].lazy1){
coverdown(root);
tr[root*2].lazy1+=tr[root].lazy1;
tr[root*2+1].lazy1+=tr[root].lazy1;
tr[root*2].maxn+=tr[root].lazy1;
tr[root*2+1].maxn+=tr[root].lazy1;
tr[root].lazy1=0;
}
}
void pushdown(ll root){coverdown(root),sumdown(root);}
void modify(ll root,ll L,ll R,ll k){
if(L>tr[root].r||tr[root].l<R) return ;
if(L<=tr[root].l&&tr[root].r<=R){
coverdown(root);
tr[root].maxn+=k;
tr[root].lazy1+=k;
return ;
}
pushdown(root);
modify(root*2,L,R,k),modify(root*2+1,L,R,k);
tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);
}
void update(ll root,ll L,ll R,ll k){
if(L>tr[root].r||tr[root].l<R) return ;
if(L<=tr[root].l&&tr[root].r<=R){
tr[root].lazy1=0;
tr[root].maxn=k;
tr[root].lazy2=k;
return ;
}
pushdown(root);
update(root*2,L,R,k),update(root*2+1,L,R,k);
tr[root].maxn=max(tr[root*2].maxn,tr[root*2+1].maxn);
}
ll query(ll root,ll L,ll R){
if(tr[root].l<L||R<tr[root].r) return 0;
if(L<=tr[root].l&&tr[root].r>=R) return tr[root].maxn;
pushdown(root);
return max(query(root*2,L,R),query(root*2+1,L,R));
}
int main(){
n=read(),q=read();
for(ll i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1;i<=n*4;i++) tr[i].lazy2=-1145141919810;
for(int i=1;i<=q;i++){
op=read();
if(op==1) l=read(),r=read(),x=read(),update(1,l,r,x);
if(op==2) l=read(),r=read(),x=read(),modify(1,l,r,x);
if(op==3) l=read(),r=read(),printf("%lld\n",query(1,l,r));
}
return 0;
}