#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5+5;
ll arr[N];
struct info {
ll prop, mx;
} tree[N*3];
void segmentTree(ll currNode, ll left, ll right) {
if (left == right) {
tree[currNode].mx = arr[left];
return;
}
ll leftNode = currNode*2, rightNode = currNode*2 + 1;
ll mid = left + (right-left)/2;
segmentTree(leftNode, left, mid);
segmentTree(rightNode, mid+1, right);
tree[currNode].mx = max(tree[leftNode].mx, tree[rightNode].mx);
}
ll query(ll currNode, ll left, ll right, ll i, ll j, ll carry = 0) {
if (i > right or j < left) return LLONG_MIN;
if (left >= i and right <= j) {
return tree[currNode].mx + carry;
}
ll leftNode = currNode*2, rightNode = currNode*2 + 1;
ll mid = left + (right-left)/2;
ll leftMax = query(leftNode, left, mid, i, j, carry + tree[currNode].prop);
ll rightMax = query(rightNode, mid + 1, right, i, j, carry + tree[currNode].prop);
return max(leftMax, rightMax);
}
void update(ll currNode, ll left, ll right, ll i, ll j, ll newValue) {
if (i > right or j < left) return;
if (left >= i and right <= j) {
tree[currNode].mx += newValue;
tree[currNode].prop += newValue;
return;
}
ll leftNode = currNode*2, rightNode = currNode*2 + 1;
ll mid = left + (right-left)/2;
update(leftNode, left, mid, i, j, newValue);
update(rightNode, mid+1, right, i, j, newValue);
tree[currNode].mx = max(tree[leftNode].mx, tree[rightNode].mx) + tree[currNode].prop;
}
signed main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int tc; cin >> tc;
test:
while (tc--) {
ll n; cin >> n;
for (ll i = 1; i <= n; i++) cin >> arr[i];
segmentTree(1, 1, n);
ll q; cin >> q;
while (q--) {
ll type, l, r; cin >> type >> l >> r;
if (type == 1) {
ll x; cin >> x;
update(1, 1, n, l, r, x);
}
else cout << query(1, 1, n, l, r) << "\n";
}
}
}