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.*;
import java.math.*;
import java.util.*;


/**
 *
 * @author Saju
 *
 */

public class Main {

    private static int dx[] = { 1, 0, -1, 0 };
    private static int dy[] = { 0, -1, 0, 1 };

    private static final long INF = Long.MAX_VALUE;
    private static final int INT_INF = Integer.MAX_VALUE;
    private static final long NEG_INF = Long.MIN_VALUE;
    private static final int NEG_INT_INF = Integer.MIN_VALUE;
    private static final double EPSILON = 1e-10;

    private static final int MAX = 1007;
    
    private static final long MOD = 1000000007;

    private static final int MAXN = 10000007;
    private static final int MAXA = 10000009;
    private static final int MAXLOG = 22;

	public static void main(String[] args) throws IOException {

		InputReader in = new InputReader(System.in);
//		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

//         InputReader in = new InputReader(new FileInputStream("src/test.in"));
//         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("src/test.out")));

/*


*/
	
		int n = in.nextInt();
		long arr[] = new long[n + 1];
		for(int i = 1; i <= n; i++) {
			arr[i] = in.nextInt();
		}
		int q = in.nextInt();
		SegmentTree segmentTree = new SegmentTree(n, arr);
		segmentTree.buildRange(1, 1, n);
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < q; i++) {
			String line = in.nextLine();
			String strs[] = line.split(" ");
			int a = Integer.parseInt(strs[0]);
			int b = Integer.parseInt(strs[1]);
			a++;
			b++;
			if(strs.length == 2) {
				
				long ans = 0;
				if(a <= b) {
					ans = segmentTree.queryRange(1, 1, n, a, b);
				}
				else {
					long val1 = segmentTree.queryRange(1, 1, n, a, n);
					long val2 = segmentTree.queryRange(1, 1, n, 1, b);
					ans = min(val1, val2);
				}
				
//				System.out.println(ans);
				sb.append(ans + "\n");
			}
			else {
				int c = Integer.parseInt(strs[2]);
				if(a <= b) {
					segmentTree.updateRange(1, 1, n, a, b, c);
				}
				else {
					segmentTree.updateRange(1, 1, n, a, n, c);
					segmentTree.updateRange(1, 1, n, 1, b, c);
				}
			}
		}
		out.print(sb.toString());
		
		in.close();
		out.flush();
		out.close();
		System.exit(0);
	}
	
	private static class SegmentTree {
		int n;
		private final int MAXN = 200007;
		private long[] tree = new long[MAXN << 2];
		private long[] lazy = new long[MAXN << 2];
		private long[] arr = new long[MAXN];

		/***
		 * 
		 * arr is 1 based index.
		 * 
		 * @param arr
		 * 
		 */
		SegmentTree(int n, long[] arr) {
			this.n = n;
			for (int i = 0; i < arr.length; i++) {
				this.arr[i] = arr[i];
			}
//			Arrays.fill(tree, INF);
//			Arrays.fill(lazy, INF);
		}

		void build(int index, int left, int right) {
			if (left == right) {
				tree[index] = arr[left];
			} else {
				int mid = (left + right) / 2;

				build(index * 2, left, mid);
				build((index * 2) + 1, mid + 1, right);
				tree[index] = max(tree[(index * 2)], tree[(index * 2) + 1]);
			}
		}

		long query(int node, int left, int right, int start, int end) {

			if (left > end || right < start) {
				return NEG_INF;
			}

			if (left >= start && right <= end) {
				return tree[node];
			}
			int mid = (left + right) / 2;
			long val1 = query(2 * node, left, mid, start, end);
			long val2 = query(2 * node + 1, mid + 1, right, start, end);

			return max(val1, val2);
		}

		void update(int node, int left, int right, int idx, long val) {
			if (left == right) {
				tree[node] += val;
			} else {
				int mid = (left + right) / 2;
				if (idx <= mid) {
					update(2 * node, left, mid, idx, val);
				} else {
					update(2 * node + 1, mid + 1, right, idx, val);
				}
				tree[node] = max(tree[(2 * node) + 1], tree[(2 * node)]);
			}
		}
		
		void shift(int node) {
			tree[2 * node] += lazy[node];
			tree[2 * node + 1] += lazy[node];
			lazy[2 * node] += lazy[node];
			lazy[2 * node + 1] += lazy[node];
			lazy[node] = 0;
		}
		void updateRange(int node, int start, int end, int l, int r, long val) {
		
//				// This node needs to be updated
//				tree[node] += lazy[node]; // Update it
//				if (start != end) {
//					lazy[node * 2] += lazy[node]; // Mark child as lazy
//					lazy[node * 2 + 1] += lazy[node]; // Mark child as lazy
//				}
//				lazy[node] = 0; // Reset it
			
			if (start > end || start > r || end < l) // Current segment is not within range [l, r]
				return;
			if (start >= l && end <= r) {
				// Segment is fully within range
				tree[node] += val;
				lazy[node] += val;
				return;
			}
			int mid = (start + end) / 2;
			shift(node);
			updateRange(node * 2, start, mid, l, r, val); // Updating left child
			updateRange(node * 2 + 1, mid + 1, end, l, r, val); // Updating right child
			tree[node] = min(tree[node * 2], tree[node * 2 + 1]); // Updating root with max value
		}

		long queryRange(int node, int start, int end, int l, int r) {
			if (start > end || start > r || end < l)
				return INF; // Out of range
//			if (lazy[node] != 0) {
//				// This node needs to be updated
//				tree[node] = lazy[node]; // Update it
//				if (start != end) {
//					lazy[node * 2] = lazy[node]; // Mark child as lazy
//					lazy[node * 2 + 1] = lazy[node]; // Mark child as lazy
//				}
//				lazy[node] = 0; // Reset it
//			}
			if (start >= l && end <= r) // Current segment is totally within range [l, r]
				return tree[node];
			
			shift(node);
			
			int mid = (start + end) / 2;
			long p1 = queryRange(node * 2, start, mid, l, r); // Query left child
			long p2 = queryRange(node * 2 + 1, mid + 1, end, l, r); // Query right child
			return min(p1, p2);
		}

		
		void buildRange(int node, int low, int high) {
			if (low == high) {
				tree[node] = arr[low];
				return;
			}

			int mid = (low + high) / 2;
			int left = node << 1;
			int right = left | 1;
			buildRange(left, low, mid);
			buildRange(right, mid + 1, high);
			tree[node] = min(tree[left], tree[right]);
		}

		void printSegmentTree() {
			System.out.println(Arrays.toString(tree));
		}

	}


	private static long bigMod(long n, long k, long m) {

        long ans = 1;
        while (k > 0) {
            if ((k & 1) == 1) {
                ans = (ans * n) % m;
            }
            n = (n * n) % m;
            k >>= 1;
        }
        return ans;
    }
    
	private static long ceil(long n, long x) {
		long div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
	}
	
    private static int ceil(int n, int x) {
        int div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
    }

    private static class Point {
        double x;
        double y;

        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        double getDistance(Point p2) {
            Point p1 = this;
            double dx = p1.x - p2.x;
            double dy = p1.y - p2.y;

            return Math.sqrt((dx * dx) + (dy * dy));
        }
    }

    private static int abs(int x) {
        if (x < 0) {
            return -x;
        }
        return x;
    }

    private static long abs(long x) {
        if(x < 0) {
            return -x;
        }
        return x;
    }

    private static int lcm(int a, int b) {
        return (a * b) / gcd(a, b);
    }

    private static int gcd(int a, int b) {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }

    private static int log(long x, int base) {
        return (int) (Math.log(x) / Math.log(base));
    }

    private static long min(long a, long b) {
        if (a < b) {
            return a;
        }
        return b;
    }

    private static int min(int a, int b) {
        if (a < b) {
            return a;
        }
        return b;
    }

    private static long max(long a, long b) {
        if (a < b) {
            return b;
        }
        return a;
    }

    private static int max(int a, int b) {
        if (a < b) {
            return b;
        }
        return a;
    }

    private static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = null;
        }

        public String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(reader.readLine());

                }
            } catch (IOException e) {
                return null;
            }
            return tokenizer.nextToken();
        }

        public String nextLine() {
            String line = null;
            try {
                tokenizer = null;
                line = reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }

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

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

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

        public boolean hasNext() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(reader.readLine());
                }
            } catch (Exception e) {
                return false;
            }
            return true;
        }
        public void close() {
        	try {
        		if(reader != null) {
        			reader.close();
        		}
        	}
        	catch(Exception e) {
        		
        	}
        	
        	
        }
    }
    
}
