In this task, Nastya asked us to write a formal statement.

An array a of length n and an array k of length n-1 are given. Two types of queries should be processed: 

  * increase a_i by x. Then if a_{i+1} < a_i + k_i, a_{i+1} becomes exactly a_i + k_i; again, if a_{i+2} < a_{i+1} + k_{i+1}, a_{i+2} becomes exactly a_{i+1} + k_{i+1}, and so far for a_{i+3}, ..., a_n; 
  * print the sum of the contiguous subarray from the l-th element to the r-th element of the array a. 



It's guaranteed that initially a_i + k_i ≤ a_{i+1} for all 1 ≤ i ≤ n-1.

Input

The first line contains a single integer n (2 ≤ n ≤ 10^{5}) — the number of elements in the array a.

The second line contains n integers a_1, a_2, …, a_n (-10^{9} ≤ a_i ≤ 10^{9}) — the elements of the array a.

The third line contains n-1 integers k_1, k_2, …, k_{n-1} (-10^{6} ≤ k_i ≤ 10^{6}) — the elements of the array k.

The fourth line contains a single integer q (1 ≤ q ≤ 10^{5}) — the number of queries.

Each of the following q lines contains a query of one of two types: 

  * if the query has the first type, the corresponding line contains the character '+' (without quotes), and then there are two integers i and x (1 ≤ i ≤ n, 0 ≤ x ≤ 10^{6}), it means that integer x is added to the i-th element of the array a as described in the statement. 
  * if the query has the second type, the corresponding line contains the character 's' (without quotes) and then there are two integers l and r (1 ≤ l ≤ r ≤ n). 

Output

For each query of the second type print a single integer in a new line — the sum of the corresponding subarray.

Examples

Input


3
1 2 3
1 -1
5
s 2 3
+ 1 2
s 1 2
+ 3 1
s 2 3


Output


5
7
8


Input


3
3 6 7
3 1
3
+ 1 3
+ 2 4
s 1 3


Output


33

Note

In the first example: 

  * after the first change a = [3, 4, 3]; 
  * after the second change a = [3, 4, 4]. 



In the second example: 

  * after the first change a = [6, 9, 10]; 
  * after the second change a = [6, 13, 14]. 
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Task {

    public static void solve() throws Exception {
	int n = nextInt();
	long[] A = new long[n];
	long[] K = new long[n-1];
	for (int i = 0; i < n; i++) {
	    A[i] = nextLong();
	}
	for (int i = 0; i < n-1; i++) {
	    K[i] = nextLong();
	}
	for (int i = 1; i < n-1; i++) {
	    K[i] += K[i-1]; //sum so far
	}
	for (int i = 0; i < n-1; i++) {
	    A[i+1] -= K[i];
	}
	for (int i = 1; i < n-1; i++) {
	    K[i] += K[i-1]; //sum so far
	}
	SegmentTree segmentTree = new SegmentTree(A);
	Map<Integer, Long> pos2count = new HashMap<>();
	LST positions = new LST(A.length);
	pos2count.put(0, A[0]);
	positions.set(0);
	for (int i = 1; i < n; i++) {
	    if(A[i] < A[i-1]) throw new RuntimeException();
	    else if(A[i] > A[i-1]) {
		long count = A[i];
		pos2count.put(i, count);
		positions.set(i);
	    }
	}
	int q = nextInt();
	for(int i=0;i<q;i++) {
	    String str = next();
	    if("+".equals(str)) {
		int ind = nextInt() - 1;
		int x = nextInt();
		int pos = positions.prev(ind);
		long v = pos2count.get(pos) + x;
		positions.set(ind);
		pos2count.put(ind, v);
		
		long delta = x;
		int nextPos = positions.next(ind+1);
		boolean lastUpdated = false;
		while(nextPos >= 0) {
		    long value = pos2count.get(nextPos);
		    if(value <= v) {
			pos2count.keySet().remove(nextPos);
			positions.unset(nextPos);
			segmentTree.updateRange(ind, nextPos-1, delta);
		    } else {
			segmentTree.updateRange(ind, nextPos-1, delta);
			lastUpdated = true;
			break;
		    }
		    ind = nextPos;
		    delta = v - value;
		    nextPos = positions.next(nextPos+1);
		}
		if (!lastUpdated) {
		    nextPos = A.length;
		    segmentTree.updateRange(ind, nextPos - 1, delta);
		}
	    } else if("s".equals(str)) {
		int from = nextInt()-1;
		int to = nextInt()-1;
		long sum = 0;
		if(to >= 1) {
		    sum += K[to-1];
		}
		if(from >= 2) {
		    sum -= K[from-2];
		}
		sum += segmentTree.queryRange(from, to);
		println(sum);
	    }
	}
    }
    
    public static void main(String[] args) throws Exception {
	try {
	    fastReader = new FastReader(System.in);
	    systemOut = new BufferedOutputStream(System.out);
	    solve();
	} finally {
	    systemOut.close();
	}
    }

    private static FastReader fastReader = null;
    private static BufferedOutputStream systemOut = null;

    public static void print(Object obj) {
	print(obj.toString());
    }

    public static void print(String str) {
	try {
	    systemOut.write(str.getBytes("utf-8"));
	} catch (Exception ex) {
	    throw new RuntimeException(ex);
	}
    }

    public static void println(Object obj) {
	println(obj.toString());
    }

    public static void println(String str) {
	try {
	    print(str);
	    systemOut.write('\n');
	} catch (Exception ex) {
	    throw new RuntimeException(ex);
	}
    }

    public static String next() {
	return fastReader.readNextToken(false);
    }

    public static String nextLine() {
	return fastReader.readNextToken(true);
    }

    public static int nextInt() {
	return Integer.parseInt(fastReader.readNextToken(false));
    }

    public static long nextLong() {
	return Long.parseLong(fastReader.readNextToken(false));
    }

    public static double nextDouble() {
	return Double.parseDouble(fastReader.readNextToken(false));
    }

    static class FastReader {
	private byte[] buf = new byte[65536];
	private int ind = 0;
	private int maxInd = -1;
	private InputStream is = null;
	private boolean eof = false;
	private boolean lastCharRead = false;

	public FastReader(InputStream is) {
	    this.is = is;
	}

	public String readNextToken(boolean endOfLine) {
	    try {
		StringBuilder sb = new StringBuilder();
		boolean found = false;
		while (true) {
		    if (lastCharRead) {
			return null;
		    } else if (ind > maxInd) {
			if (eof) {
			    lastCharRead = true;
			} else {
			    fillBuffer();
			}
		    }
		    byte b = '\n';
		    if (!lastCharRead) {
			b = buf[ind++];
		    }

		    if (b == '\r') {
			// ignore
		    } else if ((b == '\n' && endOfLine) || (Character.isWhitespace(b) && !endOfLine)) {
			if (found) {
			    break;
			}
		    } else {
			sb.append((char) b);
			found = true;
		    }
		}
		return sb.toString();
	    } catch (Exception ex) {
		throw new RuntimeException(ex);
	    }
	}

	private void fillBuffer() {
	    try {
		int read = is.read(buf, 0, buf.length);
		if (read < buf.length) {
		    eof = true;
		}
		ind = 0;
		maxInd = read - 1;
	    } catch (Exception ex) {
		throw new RuntimeException(ex);
	    }
	}
    }
    
    public static class LST {
	public long[][] set;
	public int n;
	// public int size;

	public LST(int n) {
	    this.n = n;
	    int d = 1;
	    for (int m = n; m > 1; m >>>= 6, d++)
		;

	    set = new long[d][];
	    for (int i = 0, m = n >>> 6; i < d; i++, m >>>= 6) {
		set[i] = new long[m + 1];
	    }
	    // size = 0;
	}

	// [0,r)
	public LST setRange(int r) {
	    for (int i = 0; i < set.length; i++, r = r + 63 >>> 6) {
		for (int j = 0; j < r >>> 6; j++) {
		    set[i][j] = -1L;
		}
		if ((r & 63) != 0)
		    set[i][r >>> 6] |= (1L << r) - 1;
	    }
	    return this;
	}

	// [0,r)
	public LST unsetRange(int r) {
	    if (r >= 0) {
		for (int i = 0; i < set.length; i++, r = r + 63 >>> 6) {
		    for (int j = 0; j < r + 63 >>> 6; j++) {
			set[i][j] = 0;
		    }
		    if ((r & 63) != 0)
			set[i][r >>> 6] &= ~((1L << r) - 1);
		}
	    }
	    return this;
	}

	public LST set(int pos) {
	    if (pos >= 0 && pos < n) {
		// if(!get(pos))size++;
		for (int i = 0; i < set.length; i++, pos >>>= 6) {
		    set[i][pos >>> 6] |= 1L << pos;
		}
	    }
	    return this;
	}

	public LST unset(int pos) {
	    if (pos >= 0 && pos < n) {
		// if(get(pos))size--;
		for (int i = 0; i < set.length && (i == 0 || set[i - 1][pos] == 0L); i++, pos >>>= 6) {
		    set[i][pos >>> 6] &= ~(1L << pos);
		}
	    }
	    return this;
	}

	public boolean get(int pos) {
	    return pos >= 0 && pos < n && set[0][pos >>> 6] << ~pos < 0;
	}

	public LST toggle(int pos) {
	    return get(pos) ? unset(pos) : set(pos);
	}

	public int prev(int pos) {
	    for (int i = 0; i < set.length && pos >= 0; i++, pos >>>= 6, pos--) {
		int pre = prev(set[i][pos >>> 6], pos & 63);
		if (pre != -1) {
		    pos = pos >>> 6 << 6 | pre;
		    while (i > 0)
			pos = pos << 6 | 63 - Long.numberOfLeadingZeros(set[--i][pos]);
		    return pos;
		}
	    }
	    return -1;
	}

	public int next(int pos) {
	    for (int i = 0; i < set.length && pos >>> 6 < set[i].length; i++, pos >>>= 6, pos++) {
		int nex = next(set[i][pos >>> 6], pos & 63);
		if (nex != -1) {
		    pos = pos >>> 6 << 6 | nex;
		    while (i > 0)
			pos = pos << 6 | Long.numberOfTrailingZeros(set[--i][pos]);
		    return pos;
		}
	    }
	    return -1;
	}

	private static int prev(long set, int n) {
	    long h = set << ~n;
	    if (h == 0L)
		return -1;
	    return -Long.numberOfLeadingZeros(h) + n;
	}

	private static int next(long set, int n) {
	    long h = set >>> n;
	    if (h == 0L)
		return -1;
	    return Long.numberOfTrailingZeros(h) + n;
	}

	@Override
	public String toString() {
	    List<Integer> list = new ArrayList<Integer>();
	    for (int pos = next(0); pos != -1; pos = next(pos + 1)) {
		list.add(pos);
	    }
	    return list.toString();
	}
    }

    public static class SegmentTree {
	private long[] tree;
	private long[] lazy;
	private int leafs;

	public SegmentTree(long[] arr) {
	    leafs = arr.length;
	    int size = 1;
	    while (size < leafs) {
		size *= 2;
	    }
	    tree = new long[2 * size];
	    lazy = new long[tree.length];
	    build(arr, 0, 0, arr.length - 1);
	}

	private void build(long[] arr, int node, int start, int end) {
	    if (start == end) {
		tree[node] = arr[start];
	    } else {
		int mid = (start + end) / 2;
		build(arr, 2 * node + 1, start, mid);
		build(arr, 2 * node + 2, mid + 1, end);
		tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
	    }
	}

	private void updateRange(int node, int start, int end, int l, int r, long val) {
	    if(val == 0) {
		return;
	    }
	    if (lazy[node] != 0) {
		// This node needs to be updated
		tree[node] += (end - start + 1) * lazy[node]; // Update it
		if (start != end) {
		    lazy[2 * node + 1] += lazy[node]; // Mark child as lazy
		    lazy[2 * node + 2] += 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] += (end - start + 1) * val;
		if (start != end) {
		    // Not leaf node
		    lazy[2 * node + 1] += val;
		    lazy[2 * node + 2] += val;
		}
		return;
	    }
	    int mid = (start + end) / 2;
	    updateRange(2 * node + 1, start, mid, l, r, val); // Updating left child
	    updateRange(2 * node + 2, mid + 1, end, l, r, val); // Updating
								// right child
	    tree[node] = tree[2 * node + 1] + tree[2 * node + 2]; // Updating root
							      // with max value
	}

	public void updateRange(int l, int r, long val) {
	    //println("updateRange(" + l + ", " + r + ", " + val + ");");
	    updateRange(0, 0, leafs - 1, l, r, val);
	}

	private long queryRange(int node, int start, int end, int l, int r) {
	    if (start > end || start > r || end < l)
		return 0; // Out of range
	    if (lazy[node] != 0) {
		// This node needs to be updated
		tree[node] += (end - start + 1) * lazy[node]; // Update it
		if (start != end) {
		    lazy[2 * node + 1] += lazy[node]; // Mark child as lazy
		    lazy[2 * node + 2] += 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];
	    int mid = (start + end) / 2;
	    long p1 = queryRange(2 * node + 1, start, mid, l, r); // Query left
							      // child
	    long p2 = queryRange(2 * node + 2, mid + 1, end, l, r); // Query
								    // right
								    // child
	    return (p1 + p2);
	}

	public long queryRange(int l, int r) {
	    //println("queryRange(" + l + ", " + r + ");");
	    return queryRange(0, 0, leafs - 1, l, r);
	}

	@Override
	public String toString() {
	    List<Long> list = new ArrayList<>();
	    for (int i = 0; i < tree.length; i++) {
		list.add(tree[i]);
	    }
	    return list.toString();
	}
    }
}
