#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,INF=1e15+1;
int n,m,a[N];
struct Node
{
int mmax=-INF,tag1,tag2;
}node[4*N];
void build(int w,int l,int r)
{
node[w].tag1=INF;
if(l==r)
{
node[w].mmax=a[l];
return ;
}
int mid=(l+r)/2;
build(2*w,l,mid);
build(2*w+1,mid+1,r);
node[w].mmax=max(node[2*w].mmax,node[2*w+1].mmax);
}
void pushdown(int w,int l,int r)
{
if(node[w].tag1!=INF)
{
node[w*2].mmax=node[w].tag1;
node[w*2+1].mmax=node[w].tag1;
node[w*2].tag1=node[w].tag1;
node[w*2+1].tag1=node[w].tag1;
node[w*2].tag2=0;
node[w*2+1].tag2=0;
node[w].tag1=INF;
}
if(node[w].tag2!=0)
{
node[w*2].mmax+=node[w].tag2;
node[w*2+1].mmax+=node[w].tag2;
node[w*2].tag2+=node[w].tag2;
node[w*2+1].tag2+=node[w].tag2;
node[w].tag2=0;
}
}
void assignment(int w,int l,int r,int ql,int qr,int k)
{
if(ql<=l&&r<=qr)
{
node[w].tag1=k;
node[w].mmax=k;
node[w].tag2=0;
return ;
}
if(node[w].tag1!=INF||node[w].tag2!=0) pushdown(w,l,r);
int mid=(l+r)/2;
if(ql<=mid) assignment(2*w,l,mid,ql,qr,k);
if(mid<qr) assignment(2*w+1,mid+1,r,ql,qr,k);
node[w].mmax=max(node[2*w].mmax,node[2*w+1].mmax);
}
void add(int w,int l,int r,int ql,int qr,int k)
{
if(ql<=l&&r<=qr)
{
node[w].tag2+=k;
node[w].mmax+=k;
return ;
}
if(node[w].tag1!=INF||node[w].tag2!=0) pushdown(w,l,r);
int mid=(l+r)/2;
if(ql<=mid) add(2*w,l,mid,ql,qr,k);
if(mid<qr) add(2*w+1,mid+1,r,ql,qr,k);
node[w].mmax=max(node[w].mmax,node[w].mmax);
}
int getmax(int w,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
return node[w].mmax;
}
if(node[w].tag1!=INF||node[w].tag2!=0) pushdown(w,l,r);
int mid=(l+r)/2,ans=-INF;
if(ql<=mid) ans=max(ans,getmax(2*w,l,mid,ql,qr));
if(mid<qr) ans=max(ans,getmax(2*w+1,mid+1,r,ql,qr));
return ans;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op,l,r,x;
cin>>op>>l>>r;
if(op==1)
{
cin>>x;
assignment(1,1,n,l,r,x);
}
else if(op==2)
{
cin>>x;
add(1,1,n,l,r,x);
}
else
{
cout<<getmax(1,1,n,l,r)<<endl;
}
}
return 0;
}