You are given circular array *a*<sub class="lower-index">0</sub>, *a*<sub class="lower-index">1</sub>, ..., *a*<sub class="lower-index">*n* - 1</sub>. There are two types of operations with it: 
 -  *inc*(*lf*, *rg*, *v*) — this operation increases each element on the segment [*lf*, *rg*] (inclusively) by *v*; -  *rmq*(*lf*, *rg*) — this operation returns minimal value on the segment [*lf*, *rg*] (inclusively). 
Assume segments to be circular, so if *n* = 5 and *lf* = 3, *rg* = 1, it means the index sequence: 3, 4, 0, 1.

Write program to process given sequence of operations.
The first line contains integer *n* (1 ≤ *n* ≤ 200000). The next line contains initial state of the array: *a*<sub class="lower-index">0</sub>, *a*<sub class="lower-index">1</sub>, ..., *a*<sub class="lower-index">*n* - 1</sub> ( - 10<sup class="upper-index">6</sup> ≤ *a*<sub class="lower-index">*i*</sub> ≤ 10<sup class="upper-index">6</sup>), *a*<sub class="lower-index">*i*</sub> are integer. The third line contains integer *m* (0 ≤ *m* ≤ 200000), *m* — the number of operartons. Next *m* lines contain one operation each. If line contains two integer *lf*, *rg* (0 ≤ *lf*, *rg* ≤ *n* - 1) it means *rmq* operation, it contains three integers *lf*, *rg*, *v* (0 ≤ *lf*, *rg* ≤ *n* - 1; - 10<sup class="upper-index">6</sup> ≤ *v* ≤ 10<sup class="upper-index">6</sup>) — *inc* operation.
#include<bits/stdc++.h>
#define pb push_back
#define pi pair<int,int>
#define ppi pair<pi,int>
#define ll long long int
#define vi vector<int>
#define vpi vector<pi>
#define mp make_pair
using namespace std;
const int N = 200005;
const ll INF = 1000000000100000000ll;
int n, m, arr[N], var;
ll tree[4 * N], lazy[4 * N]; 
void push_down(int i){
	if(lazy[i] < 0) return;
	tree[i] += lazy[i];
	lazy[i] = 0;
}
int get_left(int i){
	return i << 1;
}

int get_right(int i){
	return (i << 1) + 1;
}

void build_tree(int idx, int tl, int tr){
	if(tl == tr){
		tree[idx] = arr[tl];
		return;
	}
	int mid = (tl + tr) >> 1;
	int left_idx = get_left(idx), right_idx = get_right(idx);
	build_tree(left_idx, tl, mid);
	build_tree(right_idx, mid + 1, tr);
	tree[idx] = min(tree[left_idx], tree[right_idx]);	
}

void update(int idx, int tl, int tr, int l, int r, int add = 0){
	if(tl > r || tr < l) return;
	push_down(idx);
	if(l <= tl && tr <= r){
		lazy[idx] += add;
		return;
	} 
	int mid = (tl + tr) >> 1;
	int left_idx = get_left(idx), right_idx = get_right(idx);
	update(left_idx, tl, mid, l, r, add);
	update(right_idx, mid + 1, tr, l, r, add);
	tree[idx] = min(tree[left_idx], tree[right_idx]);
}

ll query(int idx, int tl, int tr, int l, int r){
	if(tl > r || tr < l) return INF;
	push_down(idx);
	if(tl == tr) return tree[idx];
	int mid = (tl + tr) >> 1;
	int left_idx = get_left(idx), right_idx = get_right(idx);
	ll left_val = query(left_idx, tl, mid, l, r);
	ll right_val = query(right_idx, mid + 1, tr, l, r);
	return min(left_val, right_val);
}

void solve(){
	for(int i = 0; i < 4 * N; ++i) tree[i] = INF, lazy[i] = 0;

	scanf("%d", &n);

	for(int i = 1; i <= n; ++i){
		scanf("%d", &arr[i]);
	}

	build_tree(1, 1, n);

	scanf("%d", &m);

	for(int i = 0; i <= m; ++i){
		vector <int> v;
		string str;
		getline(cin, str);
		stringstream ss(str);

		while (ss >> var)
			v.push_back(var);
		
		if (v.size() == 0)
			continue;

		v[0] += 1;
		v[1] += 1;
		if(v.size() == 3){
			if(v[0] <= v[1]){
				update(1, v[0], v[1], 1, n, v[2]);
			}else{
				update(1, 1, v[1], 1, n, v[2]);
				update(1, v[0], n, 1, n, v[2]);
			}
		}else if(v.size() == 2){
			ll ans = INF;
			if(v[0] <= v[1]){
				ans = min(ans, query(1, v[0], v[1], 1, n));
			}else{
				ll v1 = query(1, 1, v[1], 1, n), v2 = query(1, v[0], n, 1, n);
				ans = min(ans, v1);
				ans = min(ans, v2);
			//	cout << "test: " << v1 << " " << v2 << endl;
			}
			cout << ans << endl;
		}
	}
}
int main(){
	solve();
	return 0;
}
