#include<bits/stdc++.h>
using namespace std;
#define int __int128
int a[1000005];
struct node{
int l,r;
int lod,lazy,maxv;
}t[4000005];
inline int read(){
int g=0,f=1;
char a=getchar();
while(a>'9'||a<'0'){
if(a=='-')f=-1;
a=getchar();
}
while(a<='9'&&'0'<=a){
g=g*10+a-'0';
a=getchar();
}
return f*g;
}
inline void write(int x){
if(x<0)x=-x,putchar('-');
if(x>9)write(x/10);
putchar(x%10+'0');
return ;
}
void build(int x,int l,int r){
t[x].l=l;t[x].r=r;
if(l==r){t[x].maxv=a[l];return;}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x].maxv=max(t[x<<1].maxv,t[x<<1|1].maxv);
}
void pushup(int u){
t[u].maxv=max(t[u*2].maxv,t[u*2+1].maxv);
}
void pushdown(int u){
t[u*2].lazy+=t[u].lazy;
t[u*2+1].lazy+=t[u].lazy;
t[u*2].maxv+=t[u].lazy;
t[u*2+1].maxv+=t[u].lazy;
t[u].lazy=0;
}
void _pushdown(int u){
t[u*2].lod=t[u].lod;
t[u*2+1].lod=t[u].lod;
t[u*2].maxv=t[u].lod;
t[u*2+1].maxv=t[u].lod;
t[u].lod=0;
}
void modify(int u,int l,int r,int x){
if(t[u].l>r||t[u].r<l) return;
if(t[u].l>=l&&t[u].r<=r){
t[u].lazy+=x;
t[u].maxv+=x;
return;
}
int mid=(t[u].l+t[u].r)/2;
pushdown(u);
modify(u*2,l,r,x);
modify(u*2+1,l,r,x);
pushup(u);
}
int query(int u,int l,int r){
if(t[u].l>r||t[u].r<l) return -1e9;
if(t[u].l>=l&&t[u].r<=r){
return t[u].maxv;
}
int mid=(t[u].l+t[u].r)/2;
if(t[u].lod==0)pushdown(u);
else _pushdown(u);
int ans=-0x3f3f3f;
ans=max(ans,query(u*2,l,r));
ans=max(ans,query(u*2+1,l,r));
pushup(u);
return ans;
}
void lkas(int u,int l,int r,int x){
if(t[u].l>r||t[u].r<l) return;
if(t[u].l>=l&&t[u].r<=r){
t[u].lod=x;
t[u].maxv=x;
return;
}
int mid=(t[u].l+t[u].r)/2;
_pushdown(u);
lkas(u*2,l,r,x);
lkas(u*2+1,l,r,x);
pushup(u);
}
#define __ =read()
signed main()
{
int n,q;
n __;q __;
for(int i=1;i<=n;i++)a[i] __;
build(1,1,n);
for(int i=1;i<=q;i++)
{
int k;
k __;
if(k==1){
int l,r,x;
l __,r __,x __;
lkas(1,l,r,x);
}
if(k==2){
int l,r,x;
l __,r __,x __;
modify(1,l,r,x);
}
if(k==3){
int l,r;
l __,r __;
write(query(1,l,r));
puts("");
}
}
return 0;
}