#include <iostream>
struct Node {
long long v;
long long lazy;
long long chg;
bool jud;
};
int n = 0;
long long num[1000005] = {};
Node tr[4000005] = {};
void pushdown(int p)
{
int ls = p * 2, rs = p * 2 + 1;
if (tr[p].jud) {
tr[ls].v = tr[rs].v = tr[p].v;
tr[ls].chg = tr[rs].chg = tr[p].chg + tr[p].lazy;
tr[ls].jud = tr[rs].jud = true;
tr[ls].lazy = tr[rs].lazy = 0;
} else {
tr[ls].v += tr[p].lazy;
tr[rs].v += tr[p].lazy;
tr[ls].lazy += tr[p].lazy;
tr[rs].lazy += tr[p].lazy;
}
tr[p].lazy = 0;
tr[p].chg = 0;
tr[p].jud = false;
}
void pushup(int p)
{
int ls = p * 2, rs = p * 2 + 1;
tr[p].v = std::max(tr[ls].v, tr[rs].v);
}
void build(int l, int r, int p)
{
tr[p].v = 0;
tr[p].lazy = 0;
tr[p].chg = 0;
tr[p].jud = false;
if (l == r) {
tr[p].v = num[l];
return;
}
int ls = p * 2, rs = p * 2 + 1;
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
pushup(p);
}
void change(int l, int r, int p, int x, int y, long long v)
{
if (l > y || r < x) {
return;
}
if (l >= x && r <= y) {
tr[p].lazy = 0;
tr[p].jud = true;
tr[p].chg = v;
tr[p].v = v;
return;
}
pushdown(p);
int ls = p * 2, rs = p * 2 + 1;
int mid = (l + r) >> 1;
change(l, mid, ls, x, y, v);
change(mid + 1, r, rs, x, y, v);
pushup(p);
}
void add(int l, int r, int p, int x, int y, long long v)
{
if (l > y || r < x) {
return;
}
if (l >= x && r <= y) {
tr[p].lazy += v;
tr[p].v += v;
return;
}
pushdown(p);
int ls = p * 2, rs = p * 2 + 1;
int mid = (l + r) >> 1;
add(l, mid, ls, x, y, v);
add(mid + 1, r, rs, x, y, v);
pushup(p);
}
long long ask(int l, int r, int p, int x, int y)
{
if (l > y || r < x) {
return 0;
}
if (l >= x && r <= y) {
return tr[p].v;
}
pushdown(p);
int ls = p * 2, rs = p * 2 + 1;
int mid = (l + r) >> 1;
return std::max(ask(l, mid, ls, x, y), ask(mid + 1, r, rs, x, y));
}
int main()
{
int q = 0;
scanf("%d%d", &n, &q);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &num[i]);
}
build(1, n, 1);
while (q--) {
int op = 0;
int l = 0, r = 0;
int x = 0;
scanf("%d", &op);
scanf("%d%d", &l, &r);
if (op != 3) {
scanf("%d", &x);
}
if (op == 1) {
change(1, n, 1, l, r, x);
} else if (op == 2) {
add(1, n, 1, l, r, x);
} else {
printf("%lld\n", ask(1, n, 1, l, r));
}
}
return 0;
}