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
/*
 * @author derrick20
 */
import java.io.*;
import java.util.*;

public class betterLazyProp {

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

        int N = sc.nextInt();
        int[] arr =  new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = sc.nextInt();
        }

        SegmentTree segTree = new SegmentTree(arr);

        int Q = sc.nextInt();
        while (Q-->0) {
            String line = sc.nextLine();
            String[] info = line.split(" ");
            int l = Integer.parseInt(info[0]);
            int r = Integer.parseInt(info[1]);
//            System.out.println(segTree.display(1, 0));
            if (l <= r) {
                if (info.length == 3) {
                    int val = Integer.parseInt(info[2]);
                    segTree.updateRange(l, r, val);
                } else {
                    long ans = segTree.queryRange(l, r);
                    out.println(ans);
                }
            }
            else {
                // circular time!
                int l1 = 0;
                int r1 = r;
                int l2 = l;
                int r2 = arr.length - 1;
                if (info.length == 3) {
                    int val = Integer.parseInt(info[2]);
                    segTree.updateRange(l1, r1, val);
                    segTree.updateRange(l2, r2, val);
                }
                else {
                    long ans1 = segTree.queryRange(l1, r1);
                    long ans2 = segTree.queryRange(l2, r2);
                    out.println(Math.min(ans1, ans2));
                }
            }
        }
        out.close();
    }

    static int inf = (int) 1e9;

    static interface QueryInterface {
        public void updateRange(int l, int r, int val);
        public long queryRange(int l, int r);
    }

    // Brute-force class to test against
    static class SlowRangeQuery implements QueryInterface {
        long[] arr;

        public SlowRangeQuery(long[] arr) {
            this.arr = arr;
        }

        public void updateRange(int l, int r, int val) {
            for (int i = l; i <= r; i++) {
                arr[i] += val;
            }
        }

        public long queryRange(int l, int r) {
            long min = arr[l];
            for (int i = l; i <= r; i++) {
                min = Math.min(min, arr[i]);
            }
            return min;
        }
    }

    static class SegmentTree implements QueryInterface {
        // keep track of the lo and hi bounds controlled of a certain node
        int[] lo, hi;
        int[] arr;
        long[] tree, lazy;

        public SegmentTree(int[] arr) {
            int N = arr.length;
            this.arr = arr;
            lo = new int[4 * N + 1];
            hi = new int[4 * N + 1];
            tree = new long[4 * N + 1];
            lazy = new long[4 * N + 1];
            // we had to give up that 0th cell of memory
            // because there's no easy way to go down from it
            buildTree(1, 0, N - 1);
        }

        public void buildTree(int node, int l, int r) {
            if (l == r) {
                tree[node] = arr[l];
                lo[node] = l;
                hi[node] = r;
            }
            else {
                lo[node] = l;
                hi[node] = r;
                int mid = (l + r) / 2;
                buildTree(2 * node, l, mid);
                buildTree(2 * node + 1, mid + 1, r);
                pullUp(node);
            }
        }

        public String display(int node, int level) {
            String toRet = "";
            if (node >= tree.length)
                return "";
            toRet += display(2 * node + 1, level + 1); //recurse right
            for(int k = 0; k < level; k++)
                toRet += "\t\t\t\t";
            toRet += node + ": " + "(" + tree[node] + ", " + lo[node] + ", " + hi[node]  + "), " + lazy[node] + "\n";
            toRet += display(2 * node, level + 1); //recurse left
            return toRet;
        }

        // update a node with its children's new information, as a result
        // of potential changes due to recursion down in each subtree
        // Must use the lazy information
        public void pullUp(int node) {
            long leftVal = tree[2 * node] + lazy[2 * node];
            long rightVal = tree[2 * node + 1] + lazy[2 * node + 1];
            tree[node] = merge(leftVal, rightVal);
        }

        // transfer the lazy information stored at a node down to its children
        public void pushDown(int node) {
            lazy[2 * node] += lazy[node];
            lazy[2 * node + 1] += lazy[node];
            lazy[node] = 0;
        }

        // Depending on the use case, the segment tree may merge
        // the values of two nodes via adding, xor, etc.
        public long merge(long leftVal, long rightVal) {
            return Math.min(leftVal, rightVal);
        }

        // Always begin the updating with the root of the tree
        public void updateRange(int l, int r, int val) {
            updateRangeHelper(1, l, r, val);
        }

        // Update a range [l, r] by val
        // Recursively walk down to our children:
        // Either we are completely covered, disjoint, or partially covered
        // KEY POINT: We don't use a mid to break apart the range,
        // since we need to preserve the information about the range.
        // What we ARE splitting is our node into its children, and
        // we'll individually decide which of those children are useful.
        public void updateRangeHelper(int node, int l, int r, int val) {
            if (r < lo[node] || hi[node] < l) {
                // we are completely disjoint with the goal range
                return;
            }
            else if (l <= lo[node] && hi[node] <= r) {
                // Complete covering, let's be lazy
                lazy[node] += val;
            }
            else {
                // Partial covering, forced to recurse down.
                // We may have lazy values from previous updates, so
                // we must propagate it downward
                pushDown(node);

                // Recurse on children
                updateRangeHelper(2 * node, l, r, val);
                updateRangeHelper(2 * node + 1, l, r, val);

                // After recursion, we may have pending updates from children
                // affecting this node
                pullUp(node);
            }
        }

        public long queryRange(int l, int r) {
            return queryRangeHelper(1, l, r);
        }

        // Query the value along a range [l, r]
        // Where we are currently at a certain node and will
        // recurse downward - either being disjoint, contained, or partially
        // covered.
        public long queryRangeHelper(int node, int l, int r) {
            if (r < lo[node] || hi[node] < l) {
                // It's disjoint, so return a value that will not affect our
                // ultimate answer
                return inf;
            }
            else if (l <= lo[node] && hi[node] <= r) {
                // We must apply any lazy values that had been placed here earlier
                return tree[node] + lazy[node];
            }
            else {
                // First, propagate any pending lazy values
                pushDown(node);

                // Partial covering, so we must recurse
                // and gather information from the depths
                long leftResult = queryRangeHelper(2 * node, l, r);
                long rightResult = queryRangeHelper(2 * node + 1, l, r);

                // Technically, this pullUp can be called IMMEDIATELY after
                // pushing down, since the values aren't actually changing,
                // it's just that we lost our lazy value, (and our value no longer
                // reflects the true rangeQuery value that node represents)
                pullUp(node);

                // The lazy values will have been included already
                return merge(leftResult, rightResult);
            }
        }
    }

    static class Scanner {
        BufferedReader br;
        StringTokenizer st;

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

        Scanner(FileReader s) {
            br = new BufferedReader(s);
        }

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

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

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

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