#include <bits/stdc++.h>
#define maxn 1000005
#define endl '\n'
// #define int long long
using namespace std;
int n,q;
long long a[maxn];
struct node{
int l,r;
long long smax,lazy1,lazy2;//lazy1 加上 lazy2 修改
}t[maxn*4];
void pushup(int u){
t[u].smax=max(t[u*2].smax,t[u*2+1].smax);
}
void pushdown(int u){
if(t[u].lazy2!=LLONG_MAX)
{
t[u*2].lazy1=t[u*2+1].lazy1=0;
t[u*2].lazy2=t[u].lazy2;
t[u*2+1].lazy2=t[u].lazy2;
t[u*2].smax=t[u*2+1].smax=t[u].lazy2;
t[u].lazy2=LLONG_MAX;
}
if(t[u].lazy1!=0)
{
t[u*2].lazy1+=t[u].lazy1;
t[u*2+1].lazy1+=t[u].lazy1;
t[u*2].smax+=t[u].lazy1;
t[u*2+1].smax+=t[u].lazy1;
t[u].lazy1=0;
}
}
void build(int u,int l,int r){
t[u].l=l;t[u].r=r;
t[u].lazy1=0;t[u].lazy2=LLONG_MAX;
if(l==r)
{
t[u].smax=a[l];
return ;
}
int mid=(l+r)>>1;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
pushup(u);
}
void change1(int u,int l,int r,long long d){
if(t[u].l>=l && t[u].r<=r)
{
t[u].smax+=d;
t[u].lazy1+=d;
return ;
}
int mid=(t[u].l+t[u].r)>>1;
pushdown(u);
if(l<=mid)
change1(u*2,l,r,d);
if(r>mid)
change1(u*2+1,l,r,d);
pushup(u);
}
void change2(int u,int l,int r,long long d){
if(t[u].l>=l && t[u].r<=r)
{
t[u].smax=d;
t[u].lazy2=d;
return ;
}
int mid=(t[u].l+t[u].r)>>1;
pushdown(u);
if(l<=mid)
change2(u*2,l,r,d);
if(r>mid)
change2(u*2+1,l,r,d);
pushup(u);
}
long long ask(int u,int l,int r){
if(t[u].l>=l && t[u].r<=r)
return t[u].smax;
int mid=(t[u].l+t[u].r)>>1;
pushdown(u);
long long ans=-LLONG_MAX;
if(l<=mid)
ans=max(ans,ask(u*2,l,r));
if(mid<r)
ans=max(ans,ask(u*2+1,l,r));
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)
cin>>a[i];
build(1,1,n);
while(q--)
{
int op,x,y;
long long z;
cin>>op>>x>>y;
if(op==1)
{
cin>>z;
change2(1,x,y,z);
}
else if(op==2)
{
cin>>z;
change1(1,x,y,z);
}
else
cout<<ask(1,x,y)<<endl;
}
return 0;
}