#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,q;
ll a[1000055];
struct N{
ll l,r;
ll maxs,lazy_add,lazy_into;
} tr[4000055];
void push_down(ll c){
ll lc = 2 * c , rc = 2 * c + 1;
if(tr[c].lazy_into != -1e18){
tr[lc].lazy_into = tr[rc].lazy_into = tr[c].lazy_into;
tr[lc].lazy_add = tr[rc].lazy_add = 0;
tr[lc].maxs = tr[rc].maxs = tr[c].lazy_into;
tr[c].lazy_into = -1e18;
}
if(tr[c].lazy_add != 0){
tr[lc].lazy_add += tr[c].lazy_add , tr[rc].lazy_add += tr[c].lazy_add;
tr[lc].lazy_into = tr[rc].lazy_into = -1e18;
tr[lc].maxs += tr[c].lazy_add , tr[rc].maxs += tr[c].lazy_add;
tr[c].lazy_add = 0;
}
}
void push_up(ll c){
ll lc = 2 * c , rc = 2 * c + 1;
tr[c].maxs = max(tr[lc].maxs , tr[rc].maxs);
}
void build(ll c,ll l,ll r){
tr[c].l = l , tr[c].r = r;
tr[c].maxs = -1e18;
tr[c].lazy_into = -1e18;
if(l == r){
tr[c].maxs = a[l];
return ;
}
ll mid = (l + r) / 2;
ll lc = 2 * c , rc = 2 * c + 1;
build(lc, l, mid);
build(rc, mid+1, r);
push_up(c);
}
void update(ll c,ll l,ll r,ll k){
if(l <= tr[c].l && tr[c].r <= r){
tr[c].maxs = k;
tr[c].lazy_into = k;
tr[c].lazy_add = 0;
return ;
}
push_down(c);
ll mid = (tr[c].l + tr[c].r) / 2;
ll lc = 2 * c , rc = 2 * c + 1;
if(l <= mid) update(lc, l, r, k);
if(mid+1 <= r) update(rc, l, r, k);
push_up(c);
}
void add(ll c,ll l,ll r,ll k){
if(l <= tr[c].l && tr[c].r <= r){
tr[c].maxs += k;
tr[c].lazy_add += k;
tr[c].lazy_into = -1e18;
return ;
}
push_down(c);
ll mid = (tr[c].l + tr[c].r) / 2;
ll lc = 2 * c , rc = 2 * c + 1;
if(l <= mid) add(lc, l, r, k);
if(mid+1 <= r) add(rc, l, r, k);
push_up(c);
}
ll query(ll c,ll l,ll r){
if(l <= tr[c].l && tr[c].r <= r){
return tr[c].maxs;
}
push_down(c);
ll mid = (tr[c].l + tr[c].r) / 2 , k = -1e18;
ll lc = 2 * c , rc = 2 * c + 1;
if(l <= mid) k = max(k , query(lc, l, r));
if(mid+1 <= r) k = max(k , query(rc, l, r));
return k;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
build(1, 1, n);
ll opt,l,r,x;
while(q--){
cin>>opt>>l>>r;
if(opt == 1){
cin>>x;
update(1, l, r, x);
}
else if(opt == 2){
cin>>x;
add(1, l, r, x);
}
else cout<<query(1, l, r)<<endl;
}
return 0;
}
thx