#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct SegmentTree {
int n;
vector<ll> st, lazy;
SegmentTree(int _n) : n(_n) {
st.assign(4*n+4, 0);
lazy.assign(4*n+4, 0);
}
void build(int p, int l, int r, const vector<ll>& a) {
if (l == r) {
st[p] = a[l];
return;
}
int m = (l + r) >> 1;
build(p<<1, l, m, a);
build(p<<1|1, m+1, r, a);
st[p] = max(st[p<<1], st[p<<1|1]);
}
void apply(int p, ll val) {
st[p] += val;
lazy[p] += val;
}
void push(int p) {
if (lazy[p] != 0) {
apply(p<<1, lazy[p]);
apply(p<<1|1, lazy[p]);
lazy[p] = 0;
}
}
void update(int p, int l, int r, int i, int j, ll val) {
if (i > r || j < l) return;
if (l >= i && r <= j) {
apply(p, val);
return;
}
push(p);
int m = (l + r) >> 1;
update(p<<1, l, m, i, j, val);
update(p<<1|1, m+1, r, i, j, val);
st[p] = max(st[p<<1], st[p<<1|1]);
}
ll query(int p, int l, int r, int i, int j) {
if (i > r || j < l) return LLONG_MIN;
if (l >= i && r <= j) return st[p];
push(p);
int m = (l + r) >> 1;
return max(query(p<<1, l, m, i, j), query(p<<1|1, m+1, r, i, j));
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> T;
while (T--) {
int N;
cin >> N;
vector<ll> a(N+1);
for (int i = 1; i <= N; i++) {
cin >> a[i];
}
SegmentTree st(N);
st.build(1, 1, N, a);
int Q;
cin >> Q;
while (Q--) {
int type, L, R;
cin >> type >> L >> R;
if (type == 1) {
ll X;
cin >> X;
st.update(1, 1, N, L, R, X);
} else if (type == 2) {
ll ans = st.query(1, 1, N, L, R);
cout << ans << '\n';
}
}
}
return 0;
}