#include <climits>
#include <iostream>
#include <vector>
using namespace std;
vector<long long> lazy1;
vector<long long> lazy2;
vector<long long> tree;
vector<long long> a;
long long n;
void build(long long p = 1, long long l = 1, long long r = n){
if (l == r){
tree[p] = a[l];
return;
}
long long mid = (l + r) >> 1;
build(p * 2, l, mid);
build(p * 2 + 1, mid + 1, r);
tree[p] = max(tree[p * 2], tree[p * 2 + 1]);
}
void push_down(long long p, long long l, long long r){
if (lazy1[p] != LLONG_MIN){
if (l != r){
lazy1[p * 2] = lazy1[p];
lazy2[p * 2] = 0;
lazy1[p * 2 + 1] = lazy1[p];
lazy2[p * 2 + 1] = 0;
tree[p * 2] = lazy1[p];
tree[p * 2 + 1] = lazy1[p];
}
lazy1[p] = LLONG_MIN;
lazy2[p] = 0;
}
if (lazy2[p] != 0){
if (l != r){
lazy2[p * 2] += lazy2[p];
lazy2[p * 2 + 1] += lazy2[p];
tree[p * 2] += lazy2[p];
tree[p * 2 + 1] += lazy2[p];
}
lazy2[p] = 0;
}
}
void change1(long long x, long long y, long long z, long long p = 1, long long l = 1, long long r = n){
if (r < x || l > y){
return;
}
push_down(p, l, r);
if (l >= x && r <= y){
tree[p] = z;
lazy1[p] = z;
return;
}
long long mid = (l + r) >> 1;
change1(x, y, z, p * 2, l, mid);
change1(x, y, z, p * 2 + 1, mid + 1, r);
tree[p] = max(tree[p * 2], tree[p * 2 + 1]);
}
void change2(long long x, long long y, long long z, long long p = 1, long long l = 1, long long r = n){
if (r < x || l > y){
return;
}
push_down(p, l, r);
if (l >= x && r <= y){
tree[p] += z;
lazy2[p] += z;
return;
}
long long mid = (l + r) >> 1;
change2(x, y, z, p * 2, l, mid);
change2(x, y, z, p * 2 + 1, mid + 1, r);
tree[p] = max(tree[p * 2], tree[p * 2 + 1]);
}
long long find(long long x, long long y, long long p = 1, long long l = 1, long long r = n){
if (r < x || l > y){
return LLONG_MIN;
}
push_down(p, l, r);
if (l >= x && r <= y){
return tree[p];
}
long long mid = (l + r) >> 1;
return max(find(x, y, p * 2, l, mid), find(x, y, p * 2 + 1, mid + 1, r));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
long long q;
cin >> n >> q;
a.resize(n + 1);
for (long long i = 1; i <= n; i++){
cin >> a[i];
}
tree.resize(8 * n);
lazy1.resize(8 * n, LLONG_MIN);
lazy2.resize(8 * n);
build();
while (q--){
long long op;
cin >> op;
if (op == 1){
long long l, r, x;
cin >> l >> r >> x;
change1(l, r, x);
}
if (op == 2){
long long l, r, x;
cin >> l >> r >> x;
change2(l, r, x);
}
if (op == 3){
long long l, r;
cin >> l >> r;
cout << find(l, r) << endl;
}
}
return 0;
}