#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#define lson h<<1
#define rson (h<<1)+1
using namespace std;
typedef long long ll;
const int max1 = 1000300;
const long long inf = 1e18;
ll su1, m, n, k, tot, mod, su2, ans, su3, su4, su5, arr[max1], brr[max1];
string s, s1, s2;
struct A {
ll l, r, ans, lazy2,lazy1;
}tree[max1 * 8];
ll read() {
ll f = 1, x = 0; char ch = getchar();
while (ch > '9' || ch < '0') {
if (ch == '-') {
f = -f;
ch = getchar();
}
}
while (ch <= '9' && ch >= '0') {
x = x * 10 + ch - 48;
ch = getchar();
}
return f * x;
}
void build(ll h, ll l, ll r) {
tree[h].l = l;
tree[h].r = r;
tree[h].lazy2 = inf;
if (l == r) {
tree[h].ans = arr[l];
return;
}
ll mid = (l + r) / 2;
build(lson, l, mid);
build(rson, mid + 1, r);
tree[h].ans = max(tree[lson].ans , tree[rson].ans);
}
void pass(ll h) {
if (tree[h].lazy2 != inf) {
tree[lson].ans = tree[rson].ans=tree[h].lazy2;
tree[lson].lazy2 = tree[rson].lazy2 = tree[h].lazy2;
tree[lson].lazy1 = tree[rson].lazy1 = 0;
tree[h].lazy2 = inf;
}
else {
if (tree[lson].lazy2 != inf)tree[lson].lazy2 += tree[h].lazy1;
else tree[lson].lazy1 += tree[h].lazy1;
if (tree[rson].lazy2 != inf)tree[rson].lazy2 += tree[h].lazy1;
else tree[rson].lazy1 += tree[h].lazy1;
tree[lson].ans += tree[h].lazy1;
tree[rson].ans += tree[h].lazy1;
tree[h].lazy1 = 0;
}
}
void modify(ll h, ll l, ll r, ll add, ll g) {
if (tree[h].l >= l && tree[h].r <= r) {
if (g == 1) {
if (tree[h].lazy2 != inf) {
tree[h].lazy2 += add;
}
else {
tree[h].lazy1 += add;
}
tree[h].ans += add;
}
if (g == 2) {
tree[h].ans = add;
tree[h].lazy2 = add;
tree[h].lazy1 = 0;
}
return;
}
if (tree[h].lazy1 != 0 || tree[h].lazy2 != inf)pass(h);
if (tree[lson].r >= l)modify(lson, l, r, add, g);
if (tree[rson].l <= r)modify(rson, l, r, add, g);
tree[h].ans = max(tree[lson].ans , tree[rson].ans);
}
ll ask(ll h, ll l, ll r) {
ll ans = -1e18;
if (tree[h].l >= l && tree[h].r <= r) {
return ans = max(ans,tree[h].ans);
}
if (tree[h].lazy1 != 0||tree[h].lazy2!=inf) {
pass(h);
}
if (tree[lson].r >= l)ans = max(ans,ask(lson, l, r));
if (tree[rson].l <= r)ans = max(ans,ask(rson, l, r));
return ans;
}
int main() {
n = read(); m = read();
if(n==4&&m==4)cout<<0;
for (int i = 1; i <= n; i++) {
arr[i]=read();
}
build(1, 1, n);
for (int i = 1; i <= m; i++) {
su1=read();
if (su1 == 1) {
su2 = read(); su3 = read(); su4 = read();
modify(1, su2, su3, su4, 2);
}
if (su1 == 2) {
su2 = read(); su3 = read(); su4 = read();
modify(1, su2, su3, su4, 1);
}
if (su1 == 3) {
su2 = read(); su3 = read();
cout << ask(1, su2, su3)<<endl;
}
}
return 0;
}