#include <iostream>
#include <cstdio>
#define MAXN 1000005
#define ll long long
using namespace std;
struct node{
ll sum, tag_add, maxn, k;
}tree[MAXN*4];
ll n, q, op, l, r, x;
ll a[MAXN];
inline ll ls(ll x){
return x*2;
}
inline ll rs(ll x){
return x*2+1;
}
ll max(ll a, ll b){
return a>b?a:b;
}
void push_up(ll x){
tree[x].sum=tree[ls(x)].sum+tree[rs(x)].sum;
tree[x].maxn=max(tree[ls(x)].maxn, tree[rs(x)].maxn);
return;
}
void clear(ll x){
tree[x].sum=tree[x].k=tree[x].maxn=tree[x].tag_add=0;
}
void push_down(ll x, ll l, ll r){
ll mid=(l+r)/2;
if(tree[x].k){
clear(ls(x));
clear(rs(x));
tree[ls(x)].k = tree[rs(x)].k = tree[x].k;
tree[ls(x)].sum = tree[rs(x)].sum = tree[x].k;
tree[x].k=0;
}
tree[ls(x)].sum += tree[x].tag_add * (mid-l+1);
tree[ls(x)].tag_add += tree[x].tag_add;
tree[ls(x)].maxn += tree[x].tag_add;
tree[rs(x)].sum+=tree[x].tag_add*(r-mid);
tree[rs(x)].tag_add+=tree[x].tag_add;
tree[rs(x)].maxn+=tree[x].tag_add;
tree[x].tag_add = 0;
return;
}
void build(ll x, ll l, ll r){
if(l>r)return;
if(l==r){
tree[x].maxn=tree[x].sum=a[l];
return;
}
ll mid=(l+r)/2;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
return;
}
void change(ll x, ll l, ll r, ll L, ll R, ll k){
if(L<=l&&r<=R){
clear(x);
tree[x].k=k;
tree[x].maxn=k;
tree[x].sum=k;
return;
}
ll mid=(l+r)/2;
push_down(x,l,r);
if(L<=mid)change(ls(x), l, mid, L, R, k);
if(R>mid)change(rs(x), mid+1, r, L, R, k);
return;
}
void add(ll x, ll l, ll r, ll L, ll R, ll k){
if(L<=l&&r<=R){
tree[x].sum+=(r-l+1)*k;
tree[x].maxn+=k;
return;
}
ll mid=(l+r)/2;
push_down(x,l,r);
if(L<=mid)add(ls(x), l, mid, L, R, k);
if(R>mid)add(rs(x), mid+1, r, L, R, k);
return;
}
ll maxn(ll x, ll l, ll r, ll L, ll R){
if(L<=l&&r<=R)
return tree[x].maxn;
ll mid=(l+r)/2;
push_down(x,l,r);
ll ans=-1e18;
if(L<=mid)ans=max(maxn(ls(x), l, mid, L, R), ans);
if(R>mid)ans=max(maxn(rs(x), mid+1, r, L, R), ans);
return ans;
}
int main(){
scanf("%lld%lld", &n, &q);
for(ll i=1; i<=n; i++)scanf("%lld", &a[i]);
build(1,l,r);
for(ll i=1; i<=q; i++){
scanf("%lld", &op);
if(op==1){
scanf("%lld%lld%lld", &l, &r, &x);
change(1, 1, n, l, r, x);
}
else if(op==2){
scanf("%lld%lld%lld", &l, &r, &x);
add(1, 1, n, l, r, x);
}
else{
scanf("%lld%lld", &l, &r);
printf("%lld\n", maxn(1, 1, n, l, r));
}
}
return 0;
}