#include <bits/stdc++.h>
#define lc (u << 1)
#define rc (u << 1 | 1)
const int N = 1e6 + 10;
const long long inf = 1145141919810;
int a[N];
struct info {
long long sett, add, maxx;
}tr[N * 4];
void pushup(int u) {
tr[u].maxx = std::max(tr[lc].maxx, tr[rc].maxx);
}
void settag1(int u, int t) {
tr[u].add = 0;
tr[u].maxx = t;
tr[u].sett = t;
}
void settag2(int u, long long t) {
tr[u].maxx += t;
tr[u].add += t;
}
void pushdown(int u) {
if(tr[u].sett != -inf){
settag1(lc, tr[u].sett);
settag1(rc, tr[u].sett);
tr[u].sett = -inf;
}
else if(tr[u].add) {
settag2(lc, tr[u].add);
settag2(rc, tr[u].add);
tr[u].add = 0;
}
}
void build(int u, int l, int r) {
tr[u].sett = - inf, tr[u].add = 0;
if(l == r) {
tr[u].maxx = a[l];
return;
}
int mid = (l + r) >> 1;
build(lc, l, mid);
build(rc, mid + 1, r);
pushup(u);
}
void modify1(int u, int l, int r, int ql, int qr, int k) {
if(l == ql && r == qr) {
settag1(u, k);
return;
}
pushdown(u);
int mid = (l + r) >> 1;
if(qr <= mid) modify1(lc, l, mid, ql, qr, k);
else if(ql > mid) modify1(rc, mid + 1, r, ql, qr, k);
else {
modify1(lc, l, mid, ql, mid, k);
modify1(rc, mid + 1, r, mid + 1, qr, k);
}
pushup(u);
}
void modify2(int u, int l, int r, int ql, int qr, int k) {
if(l == ql && r == qr) {
settag2(u, k);
return;
}
pushdown(u);
int mid = (l + r) >> 1;
if(qr <= mid) modify2(lc, l, mid, ql, qr, k);
else if(ql > mid) modify2(rc, mid + 1, r, ql, qr, k);
else {
modify2(lc, l, mid, ql, mid, k);
modify2(rc, mid + 1, r, mid + 1, qr, k);
}
pushup(u);
}
long long query(int u, int l, int r, int ql, int qr) {
if(l == qr && r == qr) {
return tr[u].maxx;
}
pushdown(u);
int mid = (l + r) >> 1;
if(qr <= mid) return query(lc, l, mid, ql, qr);
else if(ql > mid) return query(rc, mid + 1, r, ql, qr);
else return std::max(query(lc, l, mid, ql, mid), query(rc, mid + 1, r, mid + 1, qr));
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0); std::cout.tie(0);
int n, q; std:: cin >> n >> q;
for(int i = 1; i <= n; i++) std:: cin >> a[i];
build(1, 1, n);
while(q--) {
int tp, l, r; std:: cin >> tp >> l >> r;
if(tp == 1) {
int x; std:: cin >> x;
modify1(1, 1, n, l, r, x);
}
else if(tp == 2) {
int x; std:: cin >> x;
modify2(1, 1, n, l, r, x);
}
else{
std:: cout << query(1, 1, n, l, r) << '\n';
}
}
}