#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6,inf=-70203201101314514;
struct node{
int x,add,change;
}mx[maxn<<2];
int a[maxn];
void build(int k,int l,int r)
{
mx[k].change=inf;
if(l==r)
{
mx[k].x=a[l];
return ;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
mx[k].x=max(mx[k<<1].x,mx[k<<1|1].x);
}
void push(int k,int l,int r,int mid)
{
if(mx[k].change==inf)
{
mx[k<<1].add+=mx[k].add;
mx[k<<1|1].add+=mx[k].add;
mx[k<<1].x+=mx[k].add;
mx[k<<1|1].x+=mx[k].add;
mx[k].add=0;
}else{
mx[k<<1].change=mx[k].change;
mx[k<<1|1].change=mx[k].change;
mx[k<<1].add+=mx[k].add;
mx[k<<1|1].add+=mx[k].add;
mx[k].add=0;
mx[k].change=inf;
}
}
void change(int k,int l,int r,int x,int y,int temp)
{
if(x>r||y<l)
return ;
if(l<=x&&y<=r)
{
mx[k].change=temp;
mx[k].x=temp;
mx[k].add=0;
return ;
}
int mid=l+r>>1;
push(k,l,r,mid);
if(x<=mid)
change(k<<1,l,mid,x,y,temp);
if(mid<y)
change(k<<1|1,mid+1,r,x,y,temp);
mx[k].x=max(mx[k<<1].x,mx[k<<1|1].x);
}
void add(int k,int l,int r,int x,int y,int temp)
{
if(x>r||y<l)
return ;
if(l<=x&&y<=r)
{
mx[k].x+=temp;
mx[k].add+=temp;
return ;
}
int mid=l+r>>1;
push(k,l,r,mid);
if(x<=mid)
add(k<<1,l,mid,x,y,temp);
if(mid<y)
add(k<<1|1,mid+1,r,x,y,temp);
mx[k].x=max(mx[k<<1].x,mx[k<<1|1].x);
}
int Query(int k,int l,int r,int x,int y)
{
int sum=-1e18;
if(x>r||y<l)
return inf;
if(l<=x&&y<=r)
return mx[k].x;
int mid=l+r>>1;
push(k,l,r,mid);
if(l<=mid)
sum=max(sum,Query(k<<1,l,r,x,y));
if(mid+1<=r)
sum=max(sum,Query(k<<1|1,l,r,x,y));
return sum;
}
signed main ()
{
int n,q,x,l,r;
scanf("%lld%lld",&n,&q);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,1,n);
for(int i=1;i<=q;i++)
{
scanf("%lld",&x);
if(x==1)
{
scanf("%lld%lld%lld",&l,&r,&x);
change(1,1,n,l,r,x);
}else if(x==2)
{
scanf("%lld%lld%lld",&l,&r,&x);
add(1,1,n,l,r,x);
}else{
scanf("%lld%lld",&l,&r);
printf("%lld\n",Query(1,1,n,l,r));
}
}
return 0;
}