#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ls p << 1
#define rs p << 1 | 1
const int N = 1e6 + 10;
int n, q, a[N], op, x, y, z;
struct T
{
int l, r, t, add, maxv;
bool f;
}t[N << 3];
void build(int p, int l, int r)
{
t[p].l = l, t[p].r = r, t[p].add = t[p].f = 0;
if(l == r)
{
t[p].maxv = a[l];
return;
}
int mid = l + r >> 1;
build(ls, l, mid), build(rs, mid + 1, r);
t[p].maxv = max(t[ls].maxv, t[rs].maxv);
}
void pushdown1(int p)
{
if(t[p].f)
{
t[ls].add = t[rs].add = 0;
t[ls].maxv = t[rs].maxv = t[p].t;
t[ls].t = t[rs].t = t[p].t;
t[p].f = 0, t[ls].f = t[rs].f = 1;
}
}
void pushdown2(int p)
{
if(t[p].add)
{
pushdown1(p);
t[ls].maxv += t[p].add, t[rs].maxv += t[p].add;
t[ls].add += t[p].add, t[rs].add += t[p].add;
t[p].add = 0;
}
}
void change1(int p, int l, int r, int k)
{
pushdown1(p);
if(l <= t[p].l && t[p].r <= r)
{
t[p].maxv += k;
t[p].add += k;
return;
}
pushdown2(p);
int mid = t[p].l + t[p].r >> 1;
if(l <= mid) change1(ls, l, r, k);
if(r > mid) change1(rs, l, r, k);
t[p].maxv = max(t[ls].maxv, t[rs].maxv);
}
void change2(int p, int l, int r, int k)
{
if(l <= t[p].l && t[p].r <= r)
{
t[p].add = 0;
t[p].maxv = k;
t[p].t = k;
t[p].f = 1;
return;
}
pushdown1(p), pushdown2(p);
int mid = t[p].l + t[p].r >> 1;
if(l <= mid) change2(ls, l, r, k);
if(r > mid) change2(rs, l, r, k);
t[p].maxv = max(t[ls].maxv, t[rs].maxv);
}
LL ask(int p, int x, int y)
{
LL ans = -1e15;
if(x <= t[p].l && t[p].r <= y) return t[p].maxv;
pushdown1(p), pushdown2(p);
int mid = t[p].l + t[p].r >> 1;
if(x <= mid) ans = max(ans, ask(ls, x, y));
if(y > mid) ans = max(ans, ask(rs, x, y));
return ans;
}
int main()
{
cin >> n >> q;
for(int i = 1; i <= n; i ++)
scanf("%d", &a[i]);
build(1, 1, n);
while(q --)
{
scanf("%d%d%d", &op, &x, &y);
if(op == 1)
{
scanf("%d", &z);
change2(1, x, y, z);
}
if(op == 2)
{
scanf("%d", &z);
change1(1, x, y, z);
}
if(op == 3) cout << ask(1, x, y) << "\n";
}
return 0;
}