rt
#include <iostream>
#include <cstdio>
#include <cctype>
#define ll long long
#define in l <= s && r >= t
#define ot l > t || r < s
#define getmid ll mid = s - ((t - s) >> 1);
using namespace std;
const int N = 1e6+5;
ll n, q, a[N];
ll tot, root;
struct node{
ll cto, add;//change_to, add
ll _max;
bool changed;
}d[N<<1];
ll ls[N<<1], rs[N<<1];
inline ll read(){
ll x = 0, w = 1;
char ch = getchar();
while(!isdigit(ch)){
if(ch == '-')w = -1;
ch = getchar();
}
while(isdigit(ch)){
x = x * 10 + (ch - '0');
ch = getchar();
}
return x * w;
}
inline void pushup(ll& p){
d[p]._max = max(d[ls[p]]._max, d[rs[p]]._max);
}
inline void pushdown(ll s, ll t, ll& p){
if(d[p].changed){
d[ls[p]].cto = d[p].cto;
d[rs[p]].cto = d[p].cto;
d[ls[p]].add = d[p].add;
d[rs[p]].add = d[p].add;
d[ls[p]]._max = d[p].cto + d[p].add;
d[rs[p]]._max = d[p].cto + d[p].add;
d[ls[p]].changed = d[rs[p]].changed = 1;
}
else {
d[ls[p]].add += d[p].add;
d[rs[p]].add += d[p].add;
d[ls[p]]._max += d[p].add;
d[rs[p]]._max += d[p].add;
}
d[p].add = d[p].cto = d[p].changed = 0;
}
inline void build(ll s, ll t, ll& p){
if(!p)p = ++tot;
d[p]._max = -1e18;
if(s == t){
d[p]._max = a[s];
return ;
}
getmid
build(s, mid, ls[p]);
build(mid+1, t, rs[p]);
pushup(p);
}
inline void change(ll l, ll r, ll k, ll s, ll t, ll& p){
if(ot)return ;
if(in){
d[p].add = 0;
d[p]._max = k;
d[p].changed = 1;
d[p].cto = k;
return ;
}
pushdown(s, t, p);
getmid
change(l, r, k, s, mid, ls[p]);
change(l, r, k, mid+1, t, rs[p]);
pushup(p);
}
inline void update(ll l, ll r, ll k, ll s, ll t, ll& p){
if(ot)return ;
if(in){
d[p].add += k;
d[p]._max += k;
return ;
}
pushdown(s, t, p);
getmid
update(l, r, k, s, mid, ls[p]);
update(l, r, k, mid+1, t, rs[p]);
pushup(p);
}
inline ll getmax(ll l, ll r, ll s, ll t, ll& p){
if(ot)return -1e18;
if(in){
return d[p]._max;
}
pushdown(s, t, p);
getmid
ll res = -1e18;
res = max(res, getmax(l, r, s, mid, ls[p]));
res = max(res, getmax(l, r, mid+1, t, rs[p]));
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
//freopen("1253.in", "r", stdin);
//freopen("1253.out", "w", stdout);
n = read(), q = read();
for(int i = 1; i <= n; i++){
a[i] = read();
}
build(1ll, n, root);
for(int i = 1; i <= q; i++){
ll opt = read(), x = read(), y = read();
if(opt == 1){
ll k = read();
change(x, y, k, 1ll, n, root);//修改
}
else if(opt == 2){
ll k = read();
update(x, y, k, 1ll, n, root);//加
}
else {
ll res = getmax(x, y, 1ll, n, root);//求区间最大值
cout << res << endl;
}
}
return 0;
}