#include<bits/stdc++.h>
using namespace std;
//using u128 = __uint128_t;
#define int long long
#define endl "\n"
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define nl cout<<"\n"
#define cnl clog<<"\n"
#define lin(n) int n;cin>>n;
#define vin vector<int>
#define pr pair<int, int>
#define pp pop_back()
#define pb push_back
#define em_pb emplace_back
#define all(x) x.begin(),x.end()
#define ppfr(v) v.erase(v.begin());
#define sum_all(v) accumulate(all(v), 0ll)
#define forn(i,n) for(int i = 0; i < n; i++)
#define Forn(i,n) for(int i = 1; i <= n; i++)
#define rforn(i,n) for(int i = n - 1; i >= 0; i--)
#define print(arr) for(auto x: arr)cout<<x<<" ";nl;
#define mprint(mp) for(auto a : mp)cout<<a.first<<" "<<a.second<<endl;
#define _log2(n) 31 - __builtin_clz(n)
#define pop_count(n) __builtin_popcount(n)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define rng(x,y) uniform_int_distribution<int>(x,y)(rng)
#ifdef DEBUG
#include<algo/debug.h>
#else
# define clog if (0) cerr
# define NB 2500
# define db(...) ""
#endif
// const int M = 998244353;
const long long INF = 1e18;
const int M = 1e9 + 7;
const int N = 2e5 + 100;
struct ST{
#define lc node << 1
#define rc node << 1 | 1
int n;
vector<int> tree, lazy, v;
ST(vector<int> v) : v(v){
n = v.size() - 1;
tree.resize(4 * n);
lazy.resize(4 * n);
build(1, 1, n);
}
inline void pull(int node){
tree[node] = max(tree[lc], tree[rc]); /*********/
}
inline void push(int node, int lo, int hi){ /*************/
if(lazy[node] == 0)return;
int val = lazy[node];
tree[node] += val;
lazy[node] = 0;
if(lo == hi)return;
lazy[lc] = lazy[lc] + val;
lazy[rc] = lazy[rc] + val;
}
void build(int node, int lo, int hi){
if(lo == hi){
tree[node] = v[lo];
return;
}
int mid = (lo + hi) / 2;
build(lc, lo, mid);
build(rc, mid + 1, hi);
pull(node);
}
void update(int node, int lo, int hi, int l, int r, int val){
push(node, lo, hi);
if(r < lo or l > hi)return;
if(lo >= l and hi <= r){
lazy[node] += val; /************/
push(node, lo, hi);
return;
}
int mid = (lo + hi) / 2;
update(lc, lo, mid, l, r, val);
update(rc, mid + 1, hi, l, r, val);
pull(node);
}
int query(int node, int lo, int hi, int l, int r){
push(node, lo, hi);
if(r < lo or l > hi)return -INF; /************/
if(lo >= l and hi <= r)return tree[node];
int mid = (lo + hi) / 2;
int q1 = query(lc, lo, mid, l, r);
int q2 = query(rc, mid + 1, hi, l, r);
return max(q1, q2); /********/
}
void update(int l, int r, int x){
update(1, 1, n, l, r, x);
}
int query(int l, int r){
return query(1, 1, n, l, r);
}
};
void _(){
lin(n);
vin v(n + 1);
Forn(i,n)cin >> v[i];
ST st(v);
lin(q);
while(q--){
int t, l, r, x;
cin >> t >> l >> r;
if(t == 2){
cout << st.query(l, r) << endl;
}else{
cin >> x;
st.update(l, r, x);
}
}
}
int32_t main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int test = 1;
cin>>test;
for(int i = 1; i <= test; i++){
// cout << "Case " << i <<": ";
_();
}
return 0;
}