Problem: Problem

Aizu Magic School is a school where people who can use magic gather. Aizu Magic School has classrooms numbered from 1 to N and a corridor connecting the classrooms. You can go through the classrooms and corridors as many times as you like. In addition, Aizu Magic School has only one route that allows you to move between any classroom u and v through 0 or more classrooms and a corridor once. A magic circle is set up in each classroom. This magic square increases or decreases the magical power of those who enter the classroom each time they enter the classroom. Please answer the following two questions to help the students move.

question 1
0 A B
I want you to output the remaining amount of magical power when you move from classroom A to B. Including increase / decrease in classrooms A and B. Also, the amount of magical power at the beginning of this question is 0 each time.

Question 2
1 A C
The amount of increase / decrease in the magical power of classroom A changes by C.

Constraints

The input satisfies the following conditions.

* 1 ≤ N ≤ 2000
* 1 ≤ Ai ≤ 2000
* 1 ≤ Bi ≤ 2000
* 1 ≤ aj, bj ≤ N
* 1 ≤ Q ≤ 1000000
* -10000 ≤ Ci ≤ 10000

Input


N
cost1
::
costN
a1 b1
::
aN-1 bN-1
Q
query1
::
queryQ


The number N of classrooms is given at the beginning of the input. The following N lines are given the amount of magical power that increases or decreases when entering each classroom. The value on the i-line corresponds to the information in the classroom on the i-th line. Corridor information is given to the following N-1 line. The corridor on the jth line represents connecting the ajth and bjth classrooms. Then the number of questions Q is given. The following Q line is given the question in the above format.

Output

Output the answer to one line for each question 1.

Example

Input

7
1
2
3
4
5
6
7
1 2
1 3
3 4
3 5
5 6
5 7
10
0 1 7
0 2 7
1 1 15
0 1 7
0 2 7
0 1 1
1 1 -15
0 1 7
0 2 7
0 1 1


Output

16
18
31
33
16
16
18
1

Solution (in CPP):

Solution:
#include<bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)n;i++)
#define all(c) (c).begin(),(c).end()
#define mp make_pair
#define pb push_back
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define dbg(x) cerr<<__LINE__<<": "<<#x<<" = "<<(x)<<endl

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pi;
const int inf = (int)1e9;
const double INF = 1e12, EPS = 1e-9;

const int N = 2000;
const int M = 8192;

int n, a[N], b[N], cost[N];
vector<vi> e;

int parent[11][N];
int depth[N];

int euler[2*N], sz;
int pos[N][2];


int seg_sz = 1;
ll dat[2*M];
inline ll query(int a, int b, int k, int l, int r){
	
	if(b <= l || a >= r) return 0;
	if(a <= l && r <= b) return dat[k];
	
	ll lch = query(a, b, k * 2 + 1, l, (l + r) / 2);
	ll rch = query(a, b, k * 2 + 2, (l + r) / 2, r);
	
	return lch + rch;
}
inline void update(int pos, int d){
	
	pos += seg_sz - 1;
	dat[pos] += d;
	
	while(1){
		if(pos == 0) break;
		pos = (pos - 1) / 2;
		dat[pos] = dat[pos * 2 + 1] + dat[pos * 2 + 2];
	}
}

void dfs(int c, int p, int d = 1){
	
	depth[c] = d;
	parent[0][c] = p;
	dat[seg_sz - 1 + sz] = cost[c];
	euler[sz] = c;
	pos[c][0] = sz++;
	
	rep(i, e[c].size()){
		int id = e[c][i];
		int to = id < 0 ? a[-id - 1] : b[id - 1];
		
		if(to != p) dfs(to, c, d + 1);
	}
	
	dat[seg_sz - 1 + sz] = -cost[c];
	euler[sz] = c;
	pos[c][1] = sz++;
}

inline int lca(int a, int b){
	if(depth[a] < depth[b]) swap(a, b);
	
	for(int i = 10; i >= 0; i--) if(depth[a] - depth[b] >> i & 1) a = parent[i][a];
	
	if(a == b) return a;
	
	for(int i = 10; i >= 0; i--) if(parent[i][a] != parent[i][b]){
		
		a = parent[i][a];
		b = parent[i][b];
	}
	return parent[0][a];
}

int main(){
	
	scanf("%d", &n);
	e.resize(n);
	
	rep(i, n) scanf("%d", cost + i);
	rep(i, n - 1){
		scanf("%d%d", a + i, b + i);
		a[i]--; b[i]--;
		
		e[a[i]].pb(i + 1);
		e[b[i]].pb(-i - 1);
	}
	
	for(; seg_sz < 2 * n; seg_sz *= 2);
	
	dfs(0, 0);
	
	rep(i, 10) rep(j, n) parent[i + 1][j] = parent[i][parent[i][j]];
	
	for(int i = seg_sz - 2; i >= 0; i--){
		
		dat[i] = dat[i * 2 + 1] + dat[i * 2 + 2];
	}
	
	#if 0
	rep(i, seg_sz) cerr<<dat[seg_sz - 1 + i]<<" ";cerr<<endl;
	rep(i, n) cerr<<pos[i][0]<<" "<<pos[i][1]<<endl;
	cerr<<"---"<<endl;
	#endif
	
	int qs; scanf("%d", &qs);
	
	while(qs--){
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		
		if(x == 0){
			y--; z--;
			
			int p = lca(y, z);
			ll ans = 0;
			
			ans += query(0, pos[y][0] + 1, 0, 0, seg_sz);
			ans += query(0, pos[z][0] + 1, 0, 0, seg_sz);
			ans -= query(0, pos[p][0] + 1, 0, 0, seg_sz) * 2;
			ans += dat[seg_sz - 1 + pos[p][0]];
			
			printf("%lld\n", ans);
		}
		else{
			y--;
			update(pos[y][0], z);
			update(pos[y][1], -z);
		}
	}
	
	return 0;
}