#include <iostream>
using namespace std;
long long a[10000005];
long long f[40000005];
long long lazym[40000005];
long long lazyadd[40000005];
long long inf = -2000000000;
void up(int i) {
f[i] = max(f[i * 2], f[i * 2 + 1]);
}
void build(int l, int r, int i) {
lazym[i] = inf;
lazyadd[i] = 0;
if (l == r) {
f[i] = a[l];
return;
}
int mid = (l + r) / 2;
build(l, mid, i * 2);
build(mid + 1, r, i * 2 + 1);
up(i);
return;
}
void down(int i) {
if (lazym[i]!=inf) {
lazyadd[i * 2] = 0;
lazyadd[i * 2 + 1] = 0;
lazym[i * 2] = lazym[i];
lazym[i * 2 + 1] = lazym[i];
f[i * 2] = lazym[i];
f[i * 2 + 1] = lazym[i];
lazym[i] = inf;
}
if (lazyadd[i] != 0) {
lazyadd[i * 2] += lazyadd[i];
lazyadd[i * 2 + 1] += lazyadd[i];
f[i * 2] += lazyadd[i];
f[i * 2 + 1] += lazyadd[i];
lazyadd[i] = 0;
}
}
void modify(int jobl, int jobr, int l, int r, int i, int x) {
if (l >= jobl && r <= jobr) {
f[i] = x;
lazym[i] = x;
lazyadd[i] = 0;
}
else {
int mid = (l + r) / 2;
down(i);
if (mid >= jobl) {
modify(jobl, jobr, l, mid, i * 2, x);
}
if (mid < jobr) {
modify(jobl, jobr, mid + 1, r, i * 2 + 1, x);
}
up(i);
}
}
void add(int jobl, int jobr, int l, int r, int i, int x) {
if (l >= jobl && r <= jobr) {
f[i] += x;
lazyadd[i] += x;
return;
}
else {
int mid = (l + r) / 2;
down(i);
if (mid >= jobl) {
add(jobl, jobr, l, mid, i * 2, x);
}
if (mid < jobr) {
add(jobl,jobr, mid + 1, r, i * 2 + 1, x);
}
up(i);
}
}
long long querymax(int jobl, int jobr, int l, int r, int i) {
if (l >= jobl && r <= jobr) {
return f[i];
}
else {
long long ans = inf;
int mid = (l + r) / 2;
down(i);
if (mid >= jobl) {
ans = max(ans, querymax(jobl, jobr, l, mid, i * 2));
}
if (mid < jobr) {
ans = max(ans, querymax(jobl, jobr, mid + 1, r, i * 2 + 1));
}
up(i);
return ans;
}
}
int main()
{
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, n, 1);
int op, l, r, x;
for (int i = 1; i <= q; i++) {
cin >> op;
if (op == 1) {
cin >> l >> r >> x;
modify(l, r, 1, n, 1, x);
}
else if (op == 2) {
cin >> l >> r >> x;
add(l, r, 1, n, 1, x);
}
else if (op == 3) {
cin >> l >> r;
int maxnum = querymax(l, r, 1, n, 1);
cout << maxnum << endl;
}
}
}