You are given circular array a0, a1, ..., an - 1. There are two types of operations with it: 

  * inc(lf, rg, v) — this operation increases each element on the segment [lf, rg] (inclusively) by v; 
  * rmq(lf, rg) — this operation returns minimal value on the segment [lf, rg] (inclusively). 



Assume segments to be circular, so if n = 5 and lf = 3, rg = 1, it means the index sequence: 3, 4, 0, 1.

Write program to process given sequence of operations.

Input

The first line contains integer n (1 ≤ n ≤ 200000). The next line contains initial state of the array: a0, a1, ..., an - 1 ( - 106 ≤ ai ≤ 106), ai are integer. The third line contains integer m (0 ≤ m ≤ 200000), m — the number of operartons. Next m lines contain one operation each. If line contains two integer lf, rg (0 ≤ lf, rg ≤ n - 1) it means rmq operation, it contains three integers lf, rg, v (0 ≤ lf, rg ≤ n - 1; - 106 ≤ v ≤ 106) — inc operation.

Output

For each rmq operation write result for it. Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).

Examples

Input

4
1 2 3 4
4
3 0
3 0 -1
0 1
2 1


Output

1
0
0

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;


public class STree {
    long [] arr,sTree,lazy;
    int N;
    public STree(long []a)
    {
    	N=a.length-1;
    	
    	arr=a;
    	sTree=new long[2*N];
    	Arrays.fill(sTree,Long.MAX_VALUE);
    	lazy=new long [2*N];
    	build(1,1,N);
    }
    public void build (int node,int b,int e )
    {
    	if(b==e)
    		sTree[node]=arr[b];
    	else {
    	int mid = b+e >> 1;
    	build(node<<1,b,mid);
    	build(node<<1|1,mid+1,e);
    
    	sTree[node]=Math.min(sTree[node<<1],sTree[node<<1|1]);
    	}
    		
    }
    public void update_point(int idx , long val,int l)
    {
    	int node=idx+N-1;
    	sTree[node]=val;
    	while(node>1)
    	{
    		node>>=1;
    		int level=(int )(Math.log(node)/Math.log(2));
    		if((l-level)%2==1)
    	      sTree[node]=sTree[node<<1]|sTree[node<<1|1];
    		else
    		  sTree[node]=sTree[node<<1]^sTree[node<<1|1];
    	}
    }
    public void update_range (int i,int j,long val)
    {
    	update_range(1,1,N,i,j,val);
    }
    public void update_range(int node,int b,int e,int i,int j,long val)
    {
    	if(b>j||e<i)
    		return;
    	if(b>=i&&e<=j)
    	{
    		sTree[node]+=val;
    		lazy[node]+=val;
    	}else 
    	{
    		int mid = b+e >>1;
    	    propagate(node,b,mid,e);
    	    update_range(node<<1,b,mid,i,j,val);
    	    update_range(node<<1|1,mid+1,e,i,j,val);
    	    sTree[node]=Math.min(sTree[node<<1],sTree[node<<1|1]);

    	}
    }
    	
    public void propagate(int node,int b,int mid ,int e)
    {
    	lazy[node<<1]+=lazy[node];
    	lazy[node<<1|1]+=lazy[node];
    	sTree[node<<1]+=lazy[node];
    	sTree[node<<1|1]+=lazy[node];
    	lazy[node]=0;

    }
    public long query(int i,int j)
    {
    	return query(1,1,N,i,j);
    }
    public long query(int node,int b,int e,int i,int j)
    {
    	if(b>j||e<i)
    		return Long.MAX_VALUE;
    	if(b>=i&&e<=j)
    		return sTree[node];
    	int mid=b+e >>1;
    	propagate(node, b, mid, e);
    	long l=query(node<<1,b,mid,i,j);
    	long r=query(node<<1|1,mid+1,e,i,j);
    	return Math.min(l, r);
    	
    }
    public static void main(String[] args) throws IOException {
    	
    	PrintWriter pw = new PrintWriter(System.out);
		Scanner sc = new Scanner(System.in); 
		
		int n=sc.nextInt();
		int N=1;
        while(N<n)N<<=1;
		long a[]=new long [N+1];
		for(int i=0;i<n;i++)
			a[i+1]=sc.nextLong();
		int m=sc.nextInt();
			
		STree st=new STree(a);
		for(int i=0;i<m;i++)
		{
			String[]in=sc.nextLine().split(" ");
			int l=0,r=0; long val=(long)1e9;
			if(in.length==3)
			{
				l=Integer.parseInt(in[0])+1;
				r=Integer.parseInt(in[1])+1;
				val=Long.parseLong(in[2]);
			}
			else {
				l=Integer.parseInt(in[0])+1;
				r=Integer.parseInt(in[1])+1;
			}
			long ans=0;
			
			if(l>r)
			{
				if(in.length==3) {
				st.update_range(l, n, val);
				st.update_range(1,r , val);
				
				}else {
					ans=Math.min(st.query(l,n), st.query(1,r));
				}
				
			}else
			{
				if(in.length==3) 
					st.update_range(l, r, val);
				else 
					ans=st.query(l,r);
			}
			if(in.length==2)
			pw.println(ans);
			pw.flush();
			
		}
		
		
	}
    
    static class Scanner {

		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}
