rt
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define pii pair<int,int>
#define pli pair<ll,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define fi first
#define se second
using namespace std;
inline ll read(){
ll k=0,flag=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')flag=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
k=(k<<1)+(k<<3)+(c^48);
c=getchar();
}
return k*flag;
}
inline void print(ll x){
if(x<0){
putchar('-');
x=-x;
}
ll y=10,len=1;
while(y<=x){
y=(y<<1)+(y<<3);
len++;
}
while(len--){
y/=10;
putchar(x/y+48);
x%=y;
}
}
inline char readc(){
char c=getchar();
while(c==' '||c=='\n')c=getchar();
return c;
}
const int N=1e6+10;
int n,q;
ll a[N];
struct node{
int l,r;
ll ma,tag,ta;
}tree[N<<2];
void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
if(l==r){
tree[i].ma=a[l];
return ;
}
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
tree[i].ma=max(tree[i<<1].ma,tree[i<<1|1].ma);
return ;
}
void pushdown(int i){
if(tree[i].tag){
tree[i<<1].tag+=tree[i].tag;
tree[i<<1|1].tag+=tree[i].tag;
tree[i<<1].ma+=tree[i].tag;
tree[i<<1|1].ma+=tree[i].tag;
tree[i].tag=0;
}
return ;
}
inline void change(int i,int l,int r,ll k){
if(l<=tree[i].l&&tree[i].r<=r){
tree[i].ma=tree[i<<1].ma=tree[i<<1|1].ma=k;
return ;
}
int mid=tree[i].l+tree[i].r>>1;
if(l<=mid)change(i<<1,l,r,k);
if(mid+1<=r)change(i<<1|1,l,r,k);
tree[i].ma=max(tree[i<<1].ma,tree[i<<1|1].ma);
return ;
}
inline void add(int i,int l,int r,ll k){
if(l<=tree[i].l&&tree[i].r<=r){
tree[i].tag+=k;
tree[i].ma+=k;
return ;
}
pushdown(i);
int mid=tree[i].l+tree[i].r>>1;
if(l<=mid)add(i<<1,l,r,k);
if(mid+1<=r)add(i<<1|1,l,r,k);
tree[i].ma=max(tree[i<<1].ma,tree[i<<1|1].ma);
return ;
}
inline ll query(int i,int l,int r){
if(l<=tree[i].l&&tree[i].r<=r)return tree[i].ma;
pushdown(i);
int mid=tree[i].l+tree[i].r>>1;
ll res=-1e18;
if(l<=mid)res=max(res,query(i<<1,l,r));
if(mid+1<=r)res=max(res,query(i<<1|1,l,r));
return res;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;++i)a[i]=read();
build(1,1,n);
while(q--){
int op=read(),l=read(),r=read();
if(op==1){
ll k=read();
change(1,l,r,k);
}
if(op==2){
ll k=read();
add(1,l,r,k);
}
if(op==3){
print(query(1,l,r));
putchar('\n');
}
}
return 0;
}