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.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class SegmentTree
{
    static final int MAXN = 200_005;
    /*public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        long[] data={5,7,6,3,1,5,7,3,2,1,4,6,3};
        segmentify(data);
        for(int i=sc.nextInt();i>0;--i)
        {
            int ch=sc.nextInt();
            if(ch==1)
                System.out.println(rangeQuery(sc.nextInt(),sc.nextInt()));
            else
                rangeUpdate(sc.nextInt(),sc.nextInt(),sc.nextLong());
            printTree();
        }
    }*/
    public static void main(String[] args)throws Exception
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb=new StringBuilder();
        
        int n;
        long[] ar=new long[n=Integer.parseInt(br.readLine().trim())];
        
        StringTokenizer st=new StringTokenizer(br.readLine());
        for(int i=0;i<ar.length;++i)ar[i]=Long.parseLong(st.nextToken());
        segmentify(ar);
            
        //printTree();
        
        for(int i=Integer.parseInt(br.readLine().trim());i>0;--i)
        {
            st=new StringTokenizer(br.readLine());
            if(st.countTokens()==2)
            {
                int u=Integer.parseInt(st.nextToken());
                int v=Integer.parseInt(st.nextToken());
                if(u<=v)sb.append(rangeQuery(u,v));
                else
                    sb.append(nodeToNode(rangeQuery(0,v),rangeQuery(u,n-1)));
                sb.append("\n");
            }
            else
            {
                int u=Integer.parseInt(st.nextToken());
                int v=Integer.parseInt(st.nextToken());
                long val=Long.parseLong(st.nextToken());
                if(u<=v)rangeUpdate(u,v,val);
                else
                {
                    rangeUpdate(0,v,val);
                    rangeUpdate(u,n-1,val);
                }
            }
            //printTree();
        }
        System.out.print(sb);
    }
    static void printTree()
    {
        for(int i=0;i<segTree.length;++i)
        {
            for(int j=0;j<segTree[i].length;++j)
                System.out.print("("+segTree[i][j]+","+pending[i][j]+")  ");
            System.out.println();
        }
    }
    
    static long dummyNode = Long.MAX_VALUE, dummyLazy = 0;
    static long nodeToNode(long a,long b)
    {
        return Math.min(a, b);
    }
    static long lazyToLazy(long a,long b)
    {
        return a+b;
    }
    static long lazyToNode(long a,long b)
    {
        return a+b;
    }
    static long valToLazy(long a)
    {
        return a;
    }
    static long valToTree(long a,long b,int arI,int arJ,int ti,int tj)
    {
        /*int ri=(1<<arI)*arJ, rj=(1<<arI)*(arJ+1)-1;
        ri= Math.max(ri, ti);   rj=Math.min(rj, tj);
        return a+b*(rj-ri+1);*/
        return a;
    }
    
    static long[][] segTree,pending;
    static void segmentify(long[] data)
    {
        int i,j;
        i = (int)Math.ceil(Math.log(data.length)/Math.log(2)) +1;
        segTree = new long[i][];    pending = new long[i][];
        
        segTree[0] = data;
        pending[0] = new long[data.length];
        Arrays.fill(pending[0], dummyLazy);
        
        for(i=1; i<segTree.length; ++i)
        {
            j = (int)Math.ceil(segTree[i-1].length /2.0);
            segTree[i] = new long[j];
            pending[i] = new long[j];   Arrays.fill(pending[i], dummyLazy);
            
            for(j=0; j<segTree[i].length; ++j)
                fillTreeAt(i,j);
        }
    }
    static void fillTreeAt(int i,int j)
    {
        pushUp(i-1,2*j);
        if(j*2 +1 >= segTree[i-1].length)
            segTree[i][j] = segTree[i-1][2*j];
        else
        {
            segTree[i][j] = nodeToNode(segTree[i-1][2*j], segTree[i-1][2*j +1]);
            pushUp(i-1, 2*j +1);
        }
    }
    static void ptUpdate(int index,long val)
    {
        segTree[0][index]=val;
        for(int i=1;i<segTree.length;++i)
            fillTreeAt(i,index>>=1);
    }
    static void pushUp(int i,int j)
    {
        if(pending[i][j] == dummyLazy)return;
        segTree[i][j] = lazyToNode(pending[i][j],segTree[i][j]);
        int ch = j<<1, jk;
        if(i>0)
            for(jk=0;jk<2 && ch+jk<pending[i-1].length;++jk)
                pending[i-1][ch+jk] = lazyToLazy(pending[i-1][ch+jk], pending[i][j]);
        pending[i][j] = dummyLazy;
    }
    
    static int[][] stack=new int[MAXN][2];
    static long rangeQuery(int ti,int tj)
    {
        long ans = dummyNode;
        int top=0,p,q,i,j;
        stack[top][0]=segTree.length-1; stack[top][1]=0;    ++top;
        while(top>0)
        {
            --top;  
            p = stack[top][0];  q = stack[top][1];
            i = (1<<p)*q;       j = (1<<p)*(q+1) -1;
            pushUp(p,q);
            
            if(ti > j || tj < i)continue;
            if(ti <= i && tj >= j)
                ans = nodeToNode(ans,segTree[p][q]);
            else
            {
                --p;                    q<<=1;
                stack[top][0] = p;      stack[top][1] = q;  ++top;
                if(q+1 < segTree[p].length)
                {
                    stack[top][0] = p;  stack[top][1] = q+1;    ++top;
                }
            }
        }
        return ans;
    }
    static void rangeUpdate(int ti,int tj,long val)
    {
        int top=0,p,q,i,j;
        stack[top][0]=segTree.length-1; stack[top][1]=0;    ++top;
        while(top>0)
        {
            --top;  
            p = stack[top][0];  q = stack[top][1];
            i = (1<<p)*q;       j = (1<<p)*(q+1) -1;
            pushUp(p,q);
            
            if(ti > j || tj < i)continue;
            if(ti <= i && tj >= j)
            {
                pending[p][q] = lazyToLazy(pending[p][q], valToLazy(val));
                pushUp(p,q);
                int jk = p+1, ch = q;
                for(;jk<segTree.length;++jk)
                    fillTreeAt(jk,ch>>=1);
            }
            else
            {
                segTree[p][q] = valToTree(segTree[p][q],val,p,q,ti,tj);
                --p;                    q<<=1;
                stack[top][0] = p;      stack[top][1] = q;  ++top;
                if(q+1 < segTree[p].length)
                {
                    stack[top][0] = p;  stack[top][1] = q+1;    ++top;
                }
            }
        }
    }
}