#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
int MIN[maxn << 2], ADD[maxn << 2];
int A[maxn], n;

void pushUp(int rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(int l, int r, int rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	int m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(int rt, int ln, int rn)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(int L, int R, int C, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	if (L <= m)updata(L, R, C, l, m, rt<<1);
	else
		updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

int query(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	int ANS = 0xffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%d", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (int i = 1; i <= n; i++)
			scanf("%d", &A[i]);
		buildtree(1, n, 1);
		int m;
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			int a, b, c; char ch;
			scanf("%d%d", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%d", &c);
				if (a < b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a < b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#define maxn 200007
using namespace std;
int MIN[maxn << 2], ADD[maxn << 2];
int A[maxn], n;

void pushUp(int rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(int l, int r, int rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	int m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(int rt, int ln, int rn)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(int L, int R, int C, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	if (L <= m)updata(L, R, C, l, m, rt<<1);
	else
		updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

int query(int L, int R, int l, int r, int rt)
{
	if (L <= l&&r <= R)
	{
		return MIN[rt];
	}
	int m = (l + r) >> 1;
	pushdown(rt, m - l + 1, r - m);
	int ANS = 0xffffff;
	if (L <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(L, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%d", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (int i = 1; i <= n; i++)
			scanf("%d", &A[i]);
		buildtree(1, n, 1);
		int m;
		scanf("%d", &m);
		for (int i = 0; i < m; i++)
		{
			int a, b, c; char ch;
			scanf("%d%d", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%d", &c);
				if (a < b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a < b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m&&R <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	else
		if (R>m&&L>m)ANS = min(ANS, query(L, R, m + 1, r, rt << 1 | 1));
		else
		{
			if (L <= m)ANS = min(ANS, query(L, m, l, m, rt << 1));

			if (R > m)ANS = min(ANS, query(m+1, R, m + 1, r, rt << 1 | 1));
		}
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if(L<=m&&R<=m)updata(L, R, C, l, m, rt << 1);
	else
		if(L>m&&R>m)updata(L, R, C, m + 1, r, rt << 1 | 1);
		else
		{
			if (L <= m)updata(L, m, C, l, m, rt << 1);

			if (R > m)	updata(m+1, R, C, m + 1, r, rt << 1 | 1);
		}
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m&&R <= m)ANS = min(ANS, query(L, R, l, m, rt << 1));
	else
		if (R>m&&L>m)ANS = min(ANS, query(L, R, m + 1, r, rt << 1 | 1));
		else
		{
			if (L <= m)ANS = min(ANS, query(L, m, l, m, rt << 1));

			if (R > m)ANS = min(ANS, query(m+1, R, m + 1, r, rt << 1 | 1));
		}
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory>
#include<memory.h>
#define maxn 200007
using namespace std;
long long MIN[maxn << 2], ADD[maxn << 2];
long long A[maxn], n;

void pushUp(long long rt)
{
	MIN[rt] = min(MIN[rt << 1], MIN[rt << 1 | 1]);
}

void buildtree(long long l, long long r, long long rt)
{
	if (l == r)
	{
		MIN[rt] = A[l];
		return;
	}
	long long m = (l+r) >> 1;
	buildtree(l, m, rt << 1);
	buildtree(m + 1, r, rt << 1 | 1);
	pushUp(rt);
}
void pushdown(long long rt)
{
	if (ADD[rt])
	{
		ADD[rt << 1] += ADD[rt];
		ADD[rt << 1 | 1] += ADD[rt];
		MIN[rt << 1] += ADD[rt];
		MIN[rt << 1 | 1] += ADD[rt];
		ADD[rt] = 0;
	}
}
void updata(long long L, long long R, long long C, long long l, long long r, long long rt)
{
	if (L <= l&&r <= R)
	{
		MIN[rt] += C;
		ADD[rt] += C;
		return;
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	if (L <= m)updata(L, R, C, l, m, rt<<1);

	if (R >  m)	updata(L, R, C, m + 1, r, rt<<1|1);
	pushUp(rt);
}

long long query(long long L, long long R, long long l, long long r, long long rt)
{
	if (L == l&&r == R)
	{
		return MIN[rt];
	}
	long long m = (l + r) >> 1;
	pushdown(rt);
	long long ANS = 0x7ffffffffff;
	if (L <= m)ANS = min(ANS, query(L, m, l, m, rt << 1));
	if(R>m)ANS = min(ANS, query(m+1, R, m+1, r, rt << 1|1));
	return ANS;
}

int main()
{
	while (scanf("%lld", &n) == 1 && n)
	{
		memset(ADD, 0, sizeof(ADD));
		for (long long i = 1; i <= n; i++)
			scanf("%lld", &A[i]);
		buildtree(1, n, 1);
		long long m;
		scanf("%lld", &m);
		for (long long i = 0; i < m; i++)
		{
			long long a, b, c; char ch;
			scanf("%lld%lld", &a, &b);
			a++; b++;
			scanf("%c", &ch);
			if(ch==' ')
			{
				scanf("%lld", &c);
				if (a <= b)
					updata(a, b, c, 1, n, 1);
				else
				{
					updata(a, n, c, 1, n, 1);
					updata(1, b, c, 1, n, 1);
				}
			}
			else
			{
				if (a <= b)
					cout << query(a, b, 1, n, 1) << endl;
				else
				{
					cout << min(query(1, b, 1, n, 1),query(a, n, 1, n, 1)) << endl;
				}
			}
		}
	}

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        lazy[(node<<1)+1]+=lazy[node];
        lazy[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        lazy[(node<<1)+1]+=lazy[node];
        lazy[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(r<start || end<l){
        return;
    }
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == 10){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
vector<ll> ans;
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        lazy[(node<<1)+1]+=lazy[node];
        lazy[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        lazy[(node<<1)+1]+=lazy[node];
        lazy[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                ans.push_back(query(l,r,0,0,n-1));
            }
            else
                ans.push_back(min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1)));
        }
        else{
            cin>>v;
            if(v == 0)
                continue;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
    for(int i=0;i<ans.size();i++)
        printf("%I64d\n",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        scanf("%ld%ld%c",&l,&r,&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            scanf("%ld",&v);
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        scanf("%I64d%I64d%c",&l,&r,&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            scanf("%I64d",&v);
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
int a[2000005],tree[8000005],lazy[8000005];
void build(int node,int start,int end){
    int temp = 0;
    if(start == end){
        tree[node] = a[start];
        return;
    }
    int mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
    temp = tree[node];
}
void update(int l,int r,int value,int node,int start,int end){
    if(r<start || end<l){
        return;
    }
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    int mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
int query(int l,int r,int node,int start,int end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    int mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    int n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == 10){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start | end<l)
        return 1e18;
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        scanf("%d%d%c",&l,&r,&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        lazy[(node<<1)+1]+=lazy[node];
        lazy[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
int a[2000005],tree[8000005],lazy[8000005];
void build(int node,int start,int end){
    int temp = 0;
    if(start == end){
        tree[node] = a[start];
        return;
    }
    int mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
    temp = tree[node];
}
void update(int l,int r,int value,int node,int start,int end){
    if(r<start || end<l){
        return;
    }
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        lazy[node] = 0;
        return;
    }
    int mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
int query(int l,int r,int node,int start,int end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start | end<l)
        return INT_MAX;
    if(l<=start && end<=r)
        return tree[node];
    int mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    int n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        cin>>l>>r;
        scanf("%c",&c);
        //cout<<int(c)<<endl;
        if(c == 10){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005],tree[8000005],lazy[8000005];
void build(ll node,ll start,ll end){
    if(start == end){
        tree[node] = a[start];
        return;
    }
    ll mid = (start+end)>>1;
    build((node<<1)+1,start,mid);
    build((node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
void update(ll l,ll r,ll value,ll node,ll start,ll end){
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(r<start || end<l){
        return;
    }
    if(l<=start && end<=r){
        tree[node]+=value;
        lazy[(node<<1)+1]+=value;
        lazy[(node<<1)+2]+=value;
        return;
    }
    ll mid = (start+end)>>1;
    update(l,r,value,(node<<1)+1,start,mid);
    update(l,r,value,(node<<1)+2,mid+1,end);
    tree[node] = min(tree[(node<<1)+1],tree[(node<<1)+2]);
}
ll query(ll l,ll r,ll node,ll start,ll end){
    if(r<start | end<l)
        return 1e18;
    if(lazy[node]){
        tree[node]+=lazy[node];
        tree[(node<<1)+1]+=lazy[node];
        tree[(node<<1)+2]+=lazy[node];
        lazy[node] = 0;
    }
    if(l<=start && end<=r)
        return tree[node];
    ll mid = (start+end)>>1;
    return min(query(l,r,(node<<1)+1,start,mid),query(l,r,(node<<1)+2,mid+1,end));
}
int main(){
    ll n,m,l,r,v;
    char c;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    build(0,0,n-1);
    memset(lazy,0,sizeof(lazy));
    cin>>m;
    while(m--){
        scanf("%d%d%c",&l,&r,&c);
        //cout<<int(c)<<endl;
        if(c == '\n'){
            if(l<=r){
                cout<<query(l,r,0,0,n-1)<<endl;
            }
            else
                cout<<min(query(l,n-1,0,0,n-1),query(0,r,0,0,n-1))<<endl;
        }
        else{
            cin>>v;
            if(l<=r)
                update(l,r,v,0,0,n-1);
            else{
                update(l,n-1,v,0,0,n-1);
                update(0,r,v,0,0,n-1);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN];

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == r) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    if (l == r) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l >= i and r <= j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    if (l == r) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

void push(int p, int l, int r) {
    if (l < r) {
        t[2*p].second += t[p].second;
        t[2*p+1].second += t[p].second;
    }
    t[p].first += t[p].second;
    t[p].second = 0;
}

ll rmq(int p, int l, int r, int i, int j)
{
    push(p, l, r);
    if (l > j or r < i) return INT_MAX;
    if (l >= i and r <= j) return t[p].first;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l >= i and r <= j) {
        t[p].second += v;
        push(p, l, r);
        return;
    }
    push(p, l, r);
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

void push(int p, int l, int r) {
    if (l < r) {
        t[2*p].second += t[p].second;
        t[2*p+1].second += t[p].second;
    }
    t[p].first += t[p].second;
    t[p].second = 0;
}

ll rmq(int p, int l, int r, int i, int j)
{
    push(p, l, r);
    if (l > j or r < i) return INT_MAX;
    if (l >= i and r <= j) return t[p].first;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l >= i and r <= j) {
        t[p].second += v;
        push(p, l, r);
        return;
    }
    push(p, l, r);
    if (l > j or r < i) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200001;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    if (l == r) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
ll t[4*MAXN];

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p] = a[l];
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p] = min(t[2*p], t[2*p+1]);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p];
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p] += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<int,int>; // {min, inc count}

V<int> a;
V<pii> t;

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

int rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, int v)
{
    if (l > j or r < i) return;
    if (l == r) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    a.resize(n);
    REP(i, n) cin >> a[i];
    cin >> m;
    t.resize(4*n);
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        V<int> v(3);
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[MAXN];

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first, t[2*p+1].first);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == r) {
        t[p].second += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200001;
int a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    if (l == r) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, j, v);
    inc(2*p+1, m+1, r, i, j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
pii t[4*MAXN]; // { val, add }

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p].first = a[l];
        t[p].second = 0;
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == i and r == j) return t[p].first + t[p].second;
    if (l == r) return INT_MAX;
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p].second += v;
        return;
    }
    if (l == r) return;
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p].first = min(t[2*p].first + t[2*p].second, t[2*p+1].first + t[2*p+1].second);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define D(x) cerr << #x << " = " << (x) << ", "
#define REP(i, k) for(int i = 0; i < (k); ++i)
#define RREP(i, k) for(int i = (k)-1; i >= 0; --i)

typedef unsigned int uint;
typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef unsigned char byte;

template<typename T> using V = vector<T>;
template<typename T, typename U> using umap = unordered_map<T,U>;
template<typename T> using uset = unordered_set<T>;
template<typename T> using min_heap = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using max_heap = priority_queue<T>;

using pii = pair<ll,ll>; // {min, inc count}

const int MAXN = 200000+10;
ll a[MAXN];
ll t[4*MAXN];

void build(int p, int l, int r)
{
    if (l > r) return;
    if (l == r) {
        t[p] = a[l];
        return;
    }
    int m = (l+r)/2;
    build(2*p, l, m);
    build(2*p+1, m+1, r);
    t[p] = min(t[2*p], t[2*p+1]);
}

ll rmq(int p, int l, int r, int i, int j)
{
    if (l > j or r < i) return INT_MAX;
    if (l == r) return t[p];
    int m = (l+r)/2;
    int lhs = rmq(2*p, l, m, i, j);
    int rhs = rmq(2*p+1, m+1, r, i, j);
    return min(lhs, rhs);
}

void inc(int p, int l, int r, int i, int j, ll v)
{
    if (l > j or r < i) return;
    if (l == i and r == j) {
        t[p] += v;
        return;
    }
    int m = (l+r)/2;
    inc(2*p, l, m, i, min(m, j), v);
    inc(2*p+1, m+1, r, max(m+1, i), j, v);
    t[p] = min(t[2*p], t[2*p+1]);
}

int main()
{
    ios::sync_with_stdio(0);
    int n, m;
    cin >> n;
    REP(i, n) cin >> a[i];
    cin >> m;
    build(1, 0, n-1);
    cin.ignore();
    REP(i, m) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        ll v[3];
        int cnt = 0;
        while (iss >> v[cnt]) {
            ++cnt;
        }
        if (cnt == 2) {
            int l = v[0], r = v[1];
            if (l <= r) {
                cout << rmq(1, 0, n-1, l, r) << endl;
            }
            else {
                cout << min(rmq(1, 0, n-1, 0, r), rmq(1, 0, n-1, l, n-1)) << endl;
            }
        }
        else {
            int l = v[0], r = v[1], k = v[2];
            if (l <= r) {
                inc(1, 0, n-1, l, r, k);
            }
            else {
                inc(1, 0, n-1, 0, r, k);
                inc(1, 0, n-1, l, n-1, k);
            }
        }
    }
}


#include <iostream>
#include <cmath>
using namespace std;

typedef string String;
typedef long long int Long;
const int MAXN = 200 * 1000;
const int POW2 = MAXN << 1;
const int SIZE = POW2 << 1;
const Long INF = (1000 * 1000 * 1000 * 1000ll);
int n;
Long ary[POW2];
Long value[SIZE];
Long potential[SIZE];

void read();
void fastIO();
void build();
Long rmq(int, int, int, int, int);
void update(int, int, int, int, int, int);
void propagate(int);
void update(int);
inline Long getMin(int);
inline int sp2gt(int);
inline int left(int);
inline int right(int);
inline int parent(int);
inline Long rmq(int, int);
inline void update(int, int, int);

int main(){
    read();
    int originalSize = n;
    build();
    int q;
    cin >> q;
    cin.ignore();
    while(q--){
        String line;
        getline(cin, line);
        int spaceIndex = line.find(' ', 0);
        int lf = stoi(line.substr(0, spaceIndex));
        int secondSpaceIndex = line.find(' ', spaceIndex + 1);
        int rg = stoi(line.substr(spaceIndex + 1, secondSpaceIndex - spaceIndex - 1));
        int l1, r1;
        int l2, r2;
        if(lf <= rg){
            l1 = lf;
            r1 = rg;
            l2 = -1;
        }
        else{
            l1 = lf;
            r1 = originalSize - 1;
            l2 = 0;
            r2 = rg;
        }
        if(secondSpaceIndex < line.size()){
            int v = stoi(line.substr(secondSpaceIndex + 1));
            update(l1, r1, v);
            if(l2 != -1)
                update(l2, r2, v);
        }
        else{
            Long m1 = rmq(l1, r1);
            Long m2 = INF;
            if(l2 != -1)
                m2 = rmq(l2, r2);
            cout << min(m1, m2) << endl;
        }
    }
    return 0;
}

void read(){
    fastIO();
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> ary[i];
}

void fastIO(){
    ios_base :: sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

void build(){
    int m = sp2gt(n);
    for(int i = n; i < m; i++)
        ary[i] = INF;
    n = m;
    int beg = n;
    int end = n << 1;
    for(int node = beg; node < end; node++)
        value[node] = ary[node - n];
    beg >>= 1;
    end >>= 1;
    while(beg){
        for(int node = beg; node < end; node++)
            value[node] = min(value[left(node)], value[right(node)]);
        beg >>= 1;
        end >>= 1;
    }
}

Long rmq(int node, int beg, int end, int l, int r){
    Long ans = INF;
    while(l > beg || r < end){
        propagate(node);
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            ans = min(ans, getMin(left(node)));
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            ans = min(ans, getMin(right(node)));
            node = left(node);
        }
        else{
            ans = min(ans, rmq(left(node), beg, mid, l, r));
            ans = min(ans, rmq(right(node), mid + 1, end, l, r));
            return ans;
        }
    }
    return min(ans, getMin(node));
}

void update(int node, int beg, int end, int l, int r, int addValue){
    while(l > beg || r < end){
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            potential[left(node)] += addValue;
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            potential[right(node)] += addValue;
            node = left(node);
        }
        else{
            update(left(node), beg , mid, l, r, addValue);
            update(right(node), mid + 1, end, l, r, addValue);
            return;
        }
    }
    potential[node] += addValue;
    update(node);
}

void propagate(int node){
    potential[left(node)] += potential[node];
    potential[right(node)] += potential[node];
    potential[node] = 0;
}

void update(int node){
    while(node > 1){
        node = parent(node);
        value[node] = min(getMin(left(node)), getMin(right(node)));
    }
}

inline Long getMin(int node){ return value[node] + potential[node]; }

inline int sp2gt(int n){ return 1 << int(log2(n) + 1); }

inline int left(int node){ return node << 1; }

inline int right(int node){ return (node << 1) + 1; }

inline int parent(int node){ return node >> 1; }

inline Long rmq(int l, int r){ return rmq(1, 0, n - 1, l, r); }

inline void update(int l, int r, int v){ update(1, 0, n - 1, l, r, v); }


#include <iostream>
using namespace std;
const int maxn=200*1000;
int n, m;
int ary[maxn];
int q[maxn][4];
long long int tree[maxn*4-1];
long long int lazy[maxn*4-1];

void read();
void build(int, int, int);
inline int left(int);
inline int right(int);
void readQueries();
int toInteger(string);
void update(int, int, int, int, int, int);
long long int rmq(int, int, int, int, int);

int main(){
	read();
	build(0, 0, n);
	readQueries();
	for(int i=0; i<m; i++){
		if(q[i][0]==3){
			if(q[i][1]<=q[i][2])
				update(0, 0, n, q[i][1], q[i][2]+1, q[i][3]);
			else{
				update(0, 0, n, q[i][1], n, q[i][3]);
				update(0, 0, n, 0, q[i][2]+1, q[i][3]);
			}
		}
		else{
			long long int ans=0;
			if(q[i][1]<=q[i][2])
				ans=rmq(0, 0, n, q[i][1], q[i][2]+1);
			else
				ans=min(rmq(0, 0, n, q[i][1], n), rmq(0, 0, n, 0, q[i][2]+1));
			cout<<ans<<endl;
		}
	}
	return 0;
}

void read(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>ary[i];
}

void build(int node, int l, int r){
	if(l==r-1)
		tree[node]=ary[l];
	else{
		int mid=(l+r)/2;
		build(left(node), l, mid);
		build(right(node), mid, r);
		tree[node]=min(tree[left(node)], tree[right(node)]);
	}
}

inline int left(int node){
	return node*2+1;
}

inline int right(int node){
	return node*2+2;
}

void readQueries(){
	cin>>m;
	cin.ignore();
	for(int i=0; i<m; i++){
		string line;
		getline(cin, line);
		string number;
		for(int j=0; j<line.size(); j++){
			if(line[j]=='-' || line[j]=='+' || isdigit(line[j]))
				number+=line[j];
			else{
				if(number!=""){
					q[i][0]++;
					q[i][q[i][0]]=toInteger(number);
				}
				number="";
			}
		}
		if(number!=""){
			q[i][0]++;
			q[i][q[i][0]]=toInteger(number);
		}
	}
}

int toInteger(string number){
	int result=0;
	int sign=1;
	int i=0;
	if(number[0]=='-'){
		sign=-1;
		i++;
	}
	if(number[0]=='+')
		i++;
	while(i<number.size()){
		result*=10;
		result+=int(number[i])-int('0');
		i++;
	}
	return result*sign;
}

void update(int node, int l, int r, int begin, int end, int v){
	if(begin==l && end==r){
		tree[node]+=v;
		lazy[node]+=v;
	}
	else{
		int mid=(l+r)/2;
		if(end<=mid)
			update(left(node), l, mid, begin, end, v);
		else if(begin>=mid)
			update(right(node), mid, r, begin, end, v);
		else{
			update(left(node), l, mid, begin, mid, v);
			update(right(node), mid, r, mid, end, v);
		}
		tree[node]=min(tree[left(node)], tree[right(node)]);
	}
}

long long int rmq(int node, int l, int r, int begin, int end){
	if(begin==l && end==r)
		return tree[node];
	else{
		int mid=(l+r)/2;
		long long int result;
		if(end<=mid)
			result=rmq(left(node), l, mid, begin, end);
		else if(begin>=mid)
			result=rmq(right(node), mid, r, begin, end);
		else
			result=min(rmq(left(node), l, mid, begin, mid), rmq(right(node), mid, r, mid, end));
		return result+lazy[node];
	}
}


#include <iostream>
using namespace std;
const int maxn=200*1000;
int n, m;
int ary[maxn];
int q[maxn][4];
long long int tree[maxn*4-1];
long long int lazy[maxn*4-1];

void read();
void build(int, int, int);
inline int left(int);
inline int right(int);
void readQueries();
int toInteger(string);
void update(int, int, int, int, int, int);
long long int rmq(int, int, int, int, int);

int main(){
	read();
	build(0, 0, n);
	readQueries();
	int counter=1;
	for(int i=0; i<m; i++){
		if(q[i][0]==3){
			if(q[i][1]<=q[i][2])
				update(0, 0, n, q[i][1], q[i][2]+1, q[i][3]);
			else{
				update(0, 0, n, q[i][1], n, q[i][3]);
				update(0, 0, n, 0, q[i][2]+1, q[i][3]);
			}
		}
		else{
			long long int ans=0;
			if(q[i][1]<=q[i][2])
				ans=rmq(0, 0, n, q[i][1], q[i][2]+1);
			else
				ans=min(rmq(0, 0, n, q[i][1], n), rmq(0, 0, n, 0, q[i][2]+1));
			cout<<ans<<endl;
		}
	}
	return 0;
}

void read(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>ary[i];
}

void build(int node, int l, int r){
	if(l==r-1)
		tree[node]=ary[l];
	else{
		int mid=(l+r)/2;
		build(left(node), l, mid);
		build(right(node), mid, r);
		tree[node]=min(tree[left(node)], tree[right(node)]);
	}
}

inline int left(int node){
	return node*2+1;
}

inline int right(int node){
	return node*2+2;
}

void readQueries(){
	cin>>m;
	cin.ignore();
	for(int i=0; i<m; i++){
		string line;
		getline(cin, line);
		string number;
		for(int j=0; j<line.size(); j++){
			if(line[j]=='-' || line[j]=='+' || isdigit(line[j]))
				number+=line[j];
			else{
				if(number!=""){
					q[i][0]++;
					q[i][q[i][0]]=toInteger(number);
				}
				number="";
			}
		}
		if(number!=""){
			q[i][0]++;
			q[i][q[i][0]]=toInteger(number);
		}
	}
}

int toInteger(string number){
	int result=0;
	int sign=1;
	int i=0;
	if(number[0]=='-'){
		sign=-1;
		i++;
	}
	if(number[0]=='+')
		i++;
	while(i<number.size()){
		result*=10;
		result+=int(number[i])-int('0');
		i++;
	}
	return result*sign;
}

void update(int node, int l, int r, int begin, int end, int v){
	if(begin==l && end==r){
		//tree[node]+=v;
		lazy[node]+=v;
	}
	else{
		int mid=(l+r)/2;
		if(end<=mid)
			update(left(node), l, mid, begin, end, v);
		else if(begin>=mid)
			update(right(node), mid, r, begin, end, v);
		else{
			update(left(node), l, mid, begin, mid, v);
			update(right(node), mid, r, mid, end, v);
		}
		tree[node]=min(tree[left(node)]+lazy[left(node)], tree[right(node)]+lazy[right(node)]);
	}
}

long long int rmq(int node, int l, int r, int begin, int end){
	if(begin==l && end==r)
		return tree[node]+lazy[node];
	else{
		int mid=(l+r)/2;
		long long int result;
		if(end<=mid)
			result=rmq(left(node), l, mid, begin, end);
		else if(begin>=mid)
			result=rmq(right(node), mid, r, begin, end);
		else
			result=min(rmq(left(node), l, mid, begin, mid), rmq(right(node), mid, r, mid, end));
		return result+lazy[node];
	}
}


#include <iostream>
using namespace std;
const int maxn=200*1000;
int n, m;
int ary[maxn];
long long int tree[(maxn<<2)-1];
long long int sum [(maxn<<2)-1];

void read();
void build(int, int, int);
inline int left(int);
inline int right(int);
int toInteger(string);
void update(int, int, int, int, int, int);
long long int minimum(int, int, int, int, int, long long int);

int main(){
	read();
	build(0, 0, n);
	cin>>m;
	cin.ignore();
	for(int i=0; i<m; i++){
		string line, number;
		getline(cin, line);
		int a[3];
		int c=0;
		for(int j=0; j<line.size(); j++){
			if(line[j]==' '){
				a[c++]=toInteger(number);
				number="";
			}
			else
				number+=line[j];
		}
		if(number.size()>0)
			a[c++]=toInteger(number);
		if(c==3){
			if(a[0]<=a[1])
				update(0, 0, n, a[0], a[1]+1, a[2]);
			else{
				update(0, 0, n, a[0], n, a[2]);
				update(0, 0, n, 0, a[1]+1, a[2]);
			}
		}
		else{
			if(a[0]<=a[1])
				cout<<minimum(0, 0, n, a[0], a[1]+1, 0)<<endl;
			else{
				long long int x=minimum(0, 0, n, a[0], n, 0);
				long long int y=minimum(0, 0, n, 0, a[1]+1, 0);
				cout<<min(x, y)<<endl;
			}
		}
	}
	return 0;
}

void read(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>ary[i];
}

void build(int node, int l, int r){
	if(l==r-1)
		tree[node]=ary[l];
	else{
		int mid=(l+r)/2;
		build(left(node), l, mid);
		build(right(node), mid, r);
		tree[node]=min(tree[left(node)], tree[right(node)]);
	}
}

inline int left(int node){
	return node*2+1;
}

inline int right(int node){
	return node*2+2;
}

int toInteger(string str){
	int sign=1;
	if(str[0]=='-'){
		sign=-1;
		str=str.substr(1, str.size());
	}
	int result=0;
	for(int i=0; i<str.size(); i++)
		result=(result*10)+int(str[i])-int('0');
	return result*sign;
}

void update(int node, int l, int r, int begin, int end, int v){
	if(begin==l && end==r){
		tree[node]+=v;
		sum[node]+=v;
	}
	else{
		int mid=(l+r)/2;
		if(end<=mid)
			update(left(node), l, mid, begin, end, v);
		else if(begin>=mid)
			update(right(node), mid, r, begin, end, v);
		else{
			update(left(node), l, mid, begin, mid, v);
			update(right(node), mid, r, mid, end, v);
		}
		tree[node]=min(tree[left(node)], tree[right(node)]);
	}
}

long long int minimum(int node, int l, int r, int begin, int end, long long int value){
	tree[node]+=value;
	sum[node]+=value;
	if(l==begin && r==end)
		return tree[node];
	else{
		int mid=(l+r)/2;
		if(end<=mid)
			return minimum(left(node), l, mid, begin, end, sum[node]);
		else if(begin>=mid)
			return minimum(right(node), mid, r, begin, end, sum[node]);
		else{
			long long int a=minimum(left(node), l, mid, begin, mid, sum[node]);
			long long int b=minimum(right(node), mid, r, mid, end, sum[node]);
			return min(a, b);
		}
	}
}


#include <iostream>
#include <cmath>
using namespace std;

typedef string String;
typedef long long int Long;
const int MAXN = 200 * 1000;
const int POW2 = MAXN << 1;
const int SIZE = POW2 << 1;
const Long INF = (1000 * 1000 * 1000 * 1000ll);
int n;
Long ary[POW2];
Long value[SIZE];
Long potential[SIZE];

void read();
void fastIO();
void build();
Long rmq(int, int, int, int, int);
void update(int, int, int, int, int, int);
void propagate(int);
void update(int);
inline Long getMin(int);
inline int sp2gt(int);
inline int left(int);
inline int right(int);
inline int parent(int);
inline Long rmq(int, int);
inline void update(int, int, int);

int main(){
    read();
    int originalSize = n;
    build();
    int q;
    cin >> q;
    cin.ignore();
    while(q--){
        String line;
        getline(cin, line);
        int spaceIndex = line.find(' ', 0);
        int lf = stoi(line.substr(0, spaceIndex));
        int secondSpaceIndex = line.find(' ', spaceIndex + 1);
        int rg = stoi(line.substr(spaceIndex + 1, secondSpaceIndex - spaceIndex - 1));
        int l1, r1;
        int l2, r2;
        if(lf <= rg){
            l1 = lf;
            r1 = rg;
            l2 = -1;
        }
        else{
            l1 = lf;
            r1 = originalSize - 1;
            l2 = 0;
            r2 = rg;
        }
        if(secondSpaceIndex < line.size()){
            int v = stoi(line.substr(secondSpaceIndex + 1));
            update(l1, r1, v);
            if(l2 != -1)
                update(l2, r2, v);
        }
        else{
            Long m1 = rmq(l1, r1);
            Long m2 = INF;
            if(l2 != -1)
                m2 = rmq(l2, r2);
            cout << min(m1, m2) << endl;
        }
    }
    return 0;
}

void read(){
    fastIO();
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> ary[i];
}

void fastIO(){
    ios_base :: sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

void build(){
    int m = sp2gt(n);
    for(int i = n; i < m; i++)
        ary[i] = INF;
    n = m;
    int beg = n;
    int end = n << 1;
    for(int node = beg; node < end; node++)
        value[node] = ary[node - n];
    beg >>= 1;
    end >>= 1;
    while(beg){
        for(int node = beg; node < end; node++)
            value[node] = min(value[left(node)], value[right(node)]);
        beg >>= 1;
        end >>= 1;
    }
}

Long rmq(int node, int beg, int end, int l, int r){
    Long ans = INF;
    while(l > beg || r < end){
        propagate(node);
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            ans = min(ans, getMin(left(node)));
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            ans = min(ans, getMin(right(node)));
            node = left(node);
        }
        else{
            ans = min(ans, rmq(left(node), beg, mid, l, r));
            ans = min(ans, rmq(right(node), mid + 1, end, l, r));
            return ans;
        }
    }
    return min(ans, getMin(node));
}

void update(int node, int beg, int end, int l, int r, int addValue){
    while(l > beg || r < end){
        propagate(node);
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            potential[left(node)] += addValue;
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            potential[right(node)] += addValue;
            node = left(node);
        }
        else{
            update(left(node), beg , mid, l, r, addValue);
            update(right(node), mid + 1, end, l, r, addValue);
            return;
        }
    }
    potential[node] += addValue;
    update(node);
}

void propagate(int node){
    potential[left(node)] += potential[node];
    potential[right(node)] += potential[node];
    potential[node] = 0;
}

void update(int node){
    while(node > 1){
        node = parent(node);
        value[node] = min(getMin(left(node)), getMin(right(node)));
    }
}

inline Long getMin(int node){ return value[node] + potential[node]; }

inline int sp2gt(int n){ return 1 << int(log2(n) + 1); }

inline int left(int node){ return node << 1; }

inline int right(int node){ return (node << 1) + 1; }

inline int parent(int node){ return node >> 1; }

inline Long rmq(int l, int r){ return rmq(1, 0, n - 1, l, r); }

inline void update(int l, int r, int v){ update(1, 0, n - 1, l, r, v); }


#include <iostream>
#include <cmath>
using namespace std;

typedef string String;
typedef long long int Long;
const int MAXN = 200 * 1000;
const int POW2 = MAXN << 1;
const int SIZE = POW2 << 1;
const Long INF = (1000 * 1000 * 1000 * 1000ll);
int n;
Long ary[POW2];
Long value[SIZE];
Long potential[SIZE];

void read();
void fastIO();
void build();
Long rmq(int, int, int, int, int);
void update(int, int, int, int, int, int);
void propagate(int);
void update(int);
inline Long getMin(int);
inline int sp2gt(int);
inline int left(int);
inline int right(int);
inline int parent(int);
inline Long rmq(int, int);
inline void update(int, int, int);

int main(){
    read();
    int originalSize = n;
    build();
    int q;
    cin >> q;
    cin.ignore();
    while(q--){
        String line;
        getline(cin, line);
        int spaceIndex = line.find(' ', 0);
        int lf = stoi(line.substr(0, spaceIndex));
        int secondSpaceIndex = line.find(' ', spaceIndex + 1);
        int rg = stoi(line.substr(spaceIndex + 1, secondSpaceIndex - spaceIndex - 1));
        int l1, r1;
        int l2, r2;
        if(lf <= rg){
            l1 = lf;
            r1 = rg;
            l2 = -1;
        }
        else{
            l1 = lf;
            r1 = originalSize - 1;
            l2 = 0;
            r2 = rg;
        }
        if(secondSpaceIndex < line.size()){
            int v = stoi(line.substr(secondSpaceIndex + 1));
            update(l1, r1, v);
            if(l2 != -1)
                update(l2, r2, v);
        }
        else{
            Long m1 = rmq(l1, r1);
            Long m2 = INF;
            if(l2 != -1)
                m2 = rmq(l2, r2);
            cout << min(m1, m2) << endl;
        }
    }
    return 0;
}

void read(){
    fastIO();
    cin >> n;
    for(int i = 0; i < n; i++)
        cin >> ary[i];
}

void fastIO(){
    ios_base :: sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}

void build(){
    int m = sp2gt(n);
    for(int i = n; i < m; i++)
        ary[i] = INF;
    n = m;
    int beg = n;
    int end = n << 1;
    for(int node = beg; node < end; node++)
        value[node] = ary[node - n];
    beg >>= 1;
    end >>= 1;
    while(beg){
        for(int node = beg; node < end; node++)
            value[node] = min(value[left(node)], value[right(node)]);
        beg >>= 1;
        end >>= 1;
    }
}

Long rmq(int node, int beg, int end, int l, int r){
    Long ans = INF;
    while(l > beg || r < end){
        propagate(node);
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            ans = min(ans, getMin(left(node)));
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            ans = min(ans, getMin(right(node)));
            node = left(node);
        }
        else{
            ans = min(ans, rmq(left(node), beg, mid, l, r));
            ans = min(ans, rmq(right(node), mid + 1, end, l, r));
            return ans;
        }
    }
    return min(ans, getMin(node));
}

void update(int node, int beg, int end, int l, int r, int addValue){
    while(l > beg || r < end){
        propagate(node);
        int mid = (beg + end) >> 1;
        if(r <= mid){
            end = mid;
            node = left(node);
        }
        else if(l > mid){
            beg = mid + 1;
            node = right(node);
        }
        else if(l <= beg){
            beg = mid + 1;
            potential[left(node)] += addValue;
            node = right(node);
        }
        else if(r >= end){
            end = mid;
            potential[right(node)] += addValue;
            node = left(node);
        }
        else{
            update(left(node), beg , mid, l, r, addValue);
            update(right(node), mid + 1, end, l, r, addValue);
            return;
        }
    }
    potential[node] += addValue;
    update(node);
}

void propagate(int node){
    value[node] += potential[node];
    potential[left(node)] += potential[node];
    potential[right(node)] += potential[node];
    potential[node] = 0;
}

void update(int node){
    while(node > 1){
        node = parent(node);
        value[node] = min(getMin(left(node)), getMin(right(node)));
    }
}

inline Long getMin(int node){ return value[node] + potential[node]; }

inline int sp2gt(int n){ return 1 << int(log2(n) + 1); }

inline int left(int node){ return node << 1; }

inline int right(int node){ return (node << 1) + 1; }

inline int parent(int node){ return node >> 1; }

inline Long rmq(int l, int r){ return rmq(1, 0, n - 1, l, r); }

inline void update(int l, int r, int v){ update(1, 0, n - 1, l, r, v); }