#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, m;
int a[1000100];
struct QvQ {
int sum, mark , mul;
} tree[4000100];
void build(int l, int r, int id) {
tree[id].mark=0;
tree[id].mul=1e18+1;
if (l == r) {
tree[id].sum = a[l];
return;
}
int mid = (l + r) / 2;
build(l, mid, id * 2);
build(mid + 1, r, id * 2 + 1);
tree[id].sum = max(tree[id * 2].sum , tree[id * 2 + 1].sum);
return;
}
void pushdown(int id, int l1, int r1, int l2, int r2) {
if(tree[id].mul!=1e18+1){
tree[id * 2].sum = tree[id].mul;
tree[id * 2 + 1].sum = tree[id].mul;
tree[id * 2].mark = 0;
tree[id * 2 + 1].mark = 0;
tree[id * 2].mul = tree[id].mul;
tree[id * 2 + 1].mul = tree[id].mul;
tree[id].mul = 1e18+1;
}
tree[id * 2].sum += tree[id].mark;
tree[id * 2].mark = tree[id].mark;
tree[id * 2 + 1].sum += tree[id].mark;
tree[id * 2 + 1].mark = tree[id].mark;
tree[id].mark = 0;
}
int query(int L, int R, int l, int r, int id) {
if (l <= L && R <= r) {
return tree[id].sum;
}
int ans = -1e18;
int mid = (L + R) / 2;
pushdown(id, L, mid, mid + 1, R);
if (l <= mid) {
ans = max(ans,query(L, mid, l, r, id * 2));
}
if (mid + 1 <= r) {
ans = max(ans,query(mid + 1, R, l, r, id * 2 + 1));
}
return ans;
}
void add1(int L, int R, int l, int r, int id, int k) {
if (l <= L && R <= r) {
tree[id].sum = k;
tree[id].mul = k ;
tree[id].mark = 0;
return;
}
int mid = (L + R) >> 1;
pushdown(id, L, mid, mid + 1, R);
if (l <= mid) {
add1(L, mid, l, r, id * 2, k);
}
if (r >= mid + 1) {
add1(mid + 1, R, l, r, id * 2 + 1, k);
}
tree[id].sum = max(tree[id * 2].sum , tree[id * 2 + 1].sum );
return;
}
void add2(int L, int R, int l, int r, int id, int k) {
if (l <= L && R <= r) {
tree[id].sum += k ;
tree[id].mark += k;
return;
}
int mid = (L + R) >> 1;
pushdown(id, L, mid, mid + 1, R);
if (l <= mid) {
add2(L, mid, l, r, id * 2, k);
}
if (r >= mid + 1) {
add2(mid + 1, R, l, r, id * 2 + 1, k);
}
tree[id].sum = max(tree[id * 2].sum , tree[id * 2 + 1].sum );
return;
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
build(1, n, 1);
int pd, x, y, k;
while (m--) {
cin >> pd >> x >> y;
if (pd == 1) {
cin >> k;
add1(1, n, x, y, 1, k);
} else if (pd == 2) {
cin >> k;
add2(1, n, x, y, 1, k);
} else {
cout << query(1, n, x, y, 1)<< endl;
}
}
return 0;
}