rt
#include <bits/stdc++.h>
#define lc p<<1
#define rc (p<<1)|1
#define int long long
using namespace std;
const int N=1e6+5;
const long long L=-1e18;
struct node
{
int l,r;
int num;
int add;
long long cover;
}c[4*N];
int a[N];
int n,q;
void pushup(int p)
{
c[p].num=max(c[lc].num,c[rc].num);
}
void cov(int p)
{
if(c[p].cover!=L)
{
c[lc].add=0;
c[rc].add=0;
c[lc].num=c[p].cover;
c[rc].num=c[p].cover;
c[lc].cover=c[p].cover;
c[rc].cover=c[p].cover;
c[p].cover=L;
}
}
void ad(int p)
{
if(c[p].add)
{
c[lc].num+=c[p].add;
c[rc].num+=c[p].add;
c[lc].add+=c[p].add;
c[rc].add+=c[p].add;
c[p].add=0;
}
}
void pushdown(int p)
{
cov(p);
ad(p);
}
void build(int p,int l,int r)
{
c[p].l=l;
c[p].r=r;
c[p].add=0;
c[p].cover=L;
if(l==r)
{
c[p].num=a[l];
return;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
}
int query(int p,int x,int y)
{
if(x>c[p].r||c[p].l>y)
{
return INT_MIN;
}
if(x<=c[p].l&&c[p].r<=y)
{
return c[p].num;
}
int mid=c[p].l+c[p].r>>1;
pushdown(p);
int ans=LLONG_MIN;
if(x<=mid)
{
ans=max(ans,query(lc,x,y));
}
if(y>mid)
{
ans=max(ans,query(rc,x,y));
}
return ans;
}
void update(int p,int x,int y,int k)
{
if(x<=c[p].l&&c[p].r<=y)
{
if(c[p].cover)
{
c[p].cover+=k;
}
else
{
c[p].add+=k;
}
c[p].num+=k;
return;
}
int mid=c[p].l+c[p].r>>1;
pushdown(p);
if(x<=mid)
{
update(lc,x,y,k);
}
if(y>mid)
{
update(rc,x,y,k);
}
pushup(p);
}
void change(int p,int x,int y,int k)
{
if(x<=c[p].l&&c[p].r<=y)
{
c[p].cover=k;
c[p].add=0;
c[p].num=k;
return;
}
int mid=c[p].l+c[p].r>>1;
pushdown(p);
if(x<=mid)
{
change(lc,x,y,k);
}
if(y>mid)
{
change(rc,x,y,k);
}
pushup(p);
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin>>n>>q;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
while(q--)
{
int t,x,y,k;
cin>>t>>x>>y;
if(t==1)
{
cin>>k;
change(1,x,y,k);
}
else if(t==2)
{
cin>>k;
update(1,x,y,k);
}
else if(t==3)
{
printf("%lld\n",query(1,x,y));
}
}
return 0;
}