__Florie_ @ 2024-11-10 00:39:27
60pts
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ldb long double
template<typename T>
inline void read(T &x){
bool f=1; x=0; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=!f; ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch-'0'); ch=getchar();}
x=(f?x:-x); return ;
}
template<typename T>
inline void print(T x){
if(x<0) {putchar('-'); x=-x;}
if(x>9) print(x/10);
putchar(x%10+'0'); return ;
}
const int inf=2e9;
int n,q,a[1000010],lazy1[4000010];
ll maxx[4000010],lazy2[4000010];
int kid,l,r,val;
void build(int k,int l,int r){
lazy1[k]=inf;
if(l==r) {maxx[k]=a[l]; return ;}
int mid=(l+r)>>1;
build(k<<1,l,mid); build((k<<1)|1,mid+1,r);
maxx[k]=max(maxx[k<<1],maxx[(k<<1)|1]); return ;
}
//有maxx就直接去掉
void pushdown(int k){
if(lazy1[k]<inf)
{
lazy1[k<<1]=lazy1[(k<<1)|1]=lazy1[k];
maxx[k<<1]=maxx[(k<<1)|1]=lazy1[k];
lazy1[k]=inf;
}
lazy2[k<<1]+=lazy2[k]; lazy2[(k<<1)|1]+=lazy2[k];
maxx[k<<1]+=lazy2[k]; maxx[(k<<1)|1]+=lazy2[k];
lazy2[k]=0; return ;
}
void update1(int k,int l,int r,int lhs,int rhs,int pts){
if(l>=lhs&&r<=rhs) {maxx[k]=lazy1[k]=pts; lazy2[k]=0; return ;}
pushdown(k);
int mid=(l+r)>>1;
if(mid>=lhs) update1(k<<1,l,mid,lhs,rhs,pts);
if(mid<rhs) update1((k<<1)|1,mid+1,r,lhs,rhs,pts);
maxx[k]=max(maxx[k<<1],maxx[(k<<1)|1]); return ;
}
void update2(int k,int l,int r,int lhs,int rhs,int pts){
if(l>=lhs&&r<=rhs){
maxx[k]+=pts;
if(lazy1[k]<inf) lazy1[k]+=pts;
else lazy2[k]+=pts; return ;
}
pushdown(k);
int mid=(l+r)>>1;
if(mid>=lhs) update2(k<<1,l,mid,lhs,rhs,pts);
if(mid<rhs) update2((k<<1)|1,mid+1,r,lhs,rhs,pts);
maxx[k]=max(maxx[k<<1],maxx[(k<<1)|1]); return ;
}
ll query(int k,int l,int r,int lhs,int rhs){
if(l>=lhs&&r<=rhs) return maxx[k];
pushdown(k);
int mid=(l+r)>>1; ll ans=-2e18;
if(mid>=lhs) ans=max(ans,query(k<<1,l,mid,lhs,rhs));
if(mid<rhs) ans=max(ans,query((k<<1)|1,mid+1,r,lhs,rhs));
return ans;
}
int main(){
read(n); read(q);
for(int i=1;i<=n;i++) read(a[i]);
build(1,1,n);
for(int i=1;i<=q;i++){
read(kid);
if(kid==1) {read(l); read(r); read(val); update1(1,1,n,l,r,val);}
else if(kid==2) {read(l); read(r); read(val); update2(1,1,n,l,r,val);}
else {read(l); read(r); printf("%lld\n",query(1,1,n,l,r));}
}
return 0;
}