#include <bits/stdc++.h>
using namespace std;
int a[500010], w1[2000010], w2[2000010], lzy1[2000010], lzy2[2000010];
void maketag1(int u, int x)
{
lzy1[u] += x, w1[u] += x, w2[u] += x;
}
void maketag2(int u, int x)
{
lzy2[u] = w1[u] = w2[u] = x;
lzy1[u] = 0;
}
void pushup(int u)
{
w1[u] = min(w1[u << 1], w1[u << 1 | 1]);
w2[u] = max(w2[u << 1], w2[u << 1 | 1]);
}
void pushdown(int u, int L, int R)
{
int M = L + R >> 1;
if (lzy2[u] > 0)
{
maketag2(u << 1, lzy2[u]);
maketag2(u << 1 | 1, lzy2[u]);
lzy2[u] = 0;
}
if (lzy1[u] > 0)
{
maketag1(u << 1, lzy1[u]);
maketag1(u << 1 | 1, lzy1[u]);
lzy1[u] = 0;
}
}
void build(int u, int L, int R)
{
if (L == R)
{
w1[u] = w2[u] = a[L];
return;
}
int M = L + R >> 1;
build(u << 1, L, M);
build(u << 1 | 1, M + 1, R);
pushup(u);
}
void update1(int u, int L, int R, int l, int r, int x)
{
if (l <= L && R <= r) maketag1(u, x);
else if (L <= r && R >= l)
{
int M = L + R >> 1;
pushdown(u, L, R);
update1(u << 1, L, M, l, r, x);
update1(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
}
void update2(int u, int L, int R, int l, int r, int x)
{
if (l <= L && R <= r)
{
if (w1[u] >= x)
{
lzy2[u] = w1[u] = w2[u] = x;
lzy1[u] = 0;
return;
}
if (w2[u] <= x) return;
int M = L + R >> 1;
pushdown(u, L, R);
update2(u << 1, L, M, l, r, x);
update2(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
else if (L <= r && R >= l)
{
int M = L + R >> 1;
pushdown(u, L, R);
update2(u << 1, L, M, l, r, x);
update2(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
}
void update3(int u, int L, int R, int l, int r, int x)
{
if (l <= L && R <= r)
{
if (w2[u] <= x)
{
lzy2[u] = w1[u] = w2[u] = x;
lzy1[u] = 0;
return;
}
if (w1[u] >= x) return;
int M = L + R >> 1;
pushdown(u, L, R);
update3(u << 1, L, M, l, r, x);
update3(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
else if (L <= r && R >= l)
{
int M = L + R >> 1;
pushdown(u, L, R);
update3(u << 1, L, M, l, r, x);
update3(u << 1 | 1, M + 1, R, l, r, x);
pushup(u);
}
}
int query(int u, int L, int R, int l, int r)
{
if (l <= L && R <= r) return w2[u];
if (L <= r && R >= l)
{
int M = L + R >> 1;
pushdown(u, L, R);
return max(query(u << 1, L, M, l, r), query(u << 1 | 1, M + 1, R, l, r));
}
else return -1e9;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, q;
cin >> n >> q;
for (register int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
for (register int i = 1; i <= q; i++)
{
int op;
cin >> op;
if (op == 1)
{
int l, r, x;
cin >> l >> r >> x;
update1(1, 1, n, l, r, x);
}
else if (op == 2)
{
int l, r, x;
cin >> l >> r >> x;
update2(1, 1, n, l, r, x);
}
else if (op == 3)
{
int l, r, x;
cin >> l >> r >> x;
update3(1, 1, n, l, r, x);
}
else
{
int l, r;
cin >> l >> r;
cout << query(1, 1, n, l, r) << endl;
}
}
return 0;
}