Iahub likes trees very much. Recently he discovered an interesting tree named propagating tree. The tree consists of n nodes numbered from 1 to n, and each node I had an initial value AI. The root of the tree is node 1.

This tree has a special Property:when a value Val was added to a value of node I, the value-val are added to values of all The Children of node I Note that when you add value-val to a child of node I, you also add-(-val) to all children of T He child of node I and so on. Look a example explanation to understand better how it works.

This tree supports the types of queries:

In order to help Iahub understand the tree better, you must answer m queries of the preceding type.

Input

The first line contains the integers n and M (1?≤?n,?m?≤?200000). The second line contains n integers a1, a2, ..., an (1?≤?ai?≤?1000). Each of the next n–1 lines contains a integers vi and UI (1?≤?vi,?ui?≤?n), meaning that there was an edge between nodes V I and UI.

Each of the next m lines contains a query in the format described above. It is guaranteed, the following constraints hold for all queries:1?≤?x?≤?n,?1?≤?val?≤?1000.

Output

For each query of type B (print the Value of node X) You must print the answer to the query on a separate line. The queries must is answered in the order given in the input.

Sample Test (s)

Input

5 5

1 2 1) 1 2

1 2

1 3

2 4

2 5

1 2 3

1 1 2

2 1

2 2

2 4

Output

3

3

0

Note

The values of the nodes is [1,?2,?1,?1,?2] at the beginning.

Then the value 3 is added to Node 2. It propagates and value-3 is added to it ' s sons, node 4 and node 5. Then it cannot propagate any more. The values of the nodes are [1,?5,?1,?? -?2,?? -?1].

Then the value 2 is added to Node 1. It propagates and value-2 is added to it ' s sons, node 2 and Node 3. From Node 2 It propagates again, adding value 2 to it ' s sons, node 4 and node 5. Node 3 has the no sons, so it cannot propagate from there. The values of the nodes are [3,?3,?? -?1,?0,?1].

You can see all the definitions on the tree at the following link:http://en.wikipedia.org/wiki/tree_ (Graph_theory)

It's obvious to run a Dfs to get the timestamp, but it's not enough, here, with a certain number of nodes, its son to subtract that number, his son's son to add that number, so we will be based on the depth of the odd couple, the time stamp into 2 arrays, the establishment of 2 segment tree

`/************************************************************************* > File name:cf225-e.cpp > Auth Or:alex > Mail: [email protected] > Created time:2015 April 21 Tuesday 21:11 04 seconds ******************************** ****************************************/#include <functional>#include <algorithm>#include <iostream>#include <fstream>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <queue>#include <stack>#include <map>#include <bitset>#include <set>#include <vector>using namespace STD;Const DoublePI =ACOs(-1.0);Const intINF =0x3f3f3f3f;Const DoubleEPS =1e-15;typedef Long LongLL;typedefPair <int,int> PLL;Static Const intN =300010;intPar[n];intOddl[n];intOddr[n];intEvenl[n];intEvenr[n];intSubl[n];intSubr[n];intDep[n];intArr[n];intNow[n];intSta[n];intIs_leaf[n];structnode{intAddintL, R;intsum;} tree[2][n <<2];structEDGE {intto;intNXT;} Edge[n <<1];intHead[n], tot;voidAddedge (intFromintTo) {edge[tot].to = to; EDGE[TOT].NXT = Head[from]; Head[from] = tot++;}voidBuild (node tree[],intPintLintr) {tree[p].l = l; TREE[P].R = R; Tree[p].add =0;if(L = = r) {tree[p].sum = now[l];return; }intMid = (L + r) >>1; Build (tree, p <<1, L, mid); Build (tree, p <<1|1, Mid +1, R); Tree[p].sum = Tree[p <<1].sum + tree[p <<1|1].sum;}voidPushdown (node tree[],intP) {if(Tree[p].add) {Tree[p <<1].add + = Tree[p].add; Tree[p <<1|1].add + = Tree[p].add;intm = tree[p <<1].r-tree[p <<1].L +1; Tree[p <<1].sum + = m * TREE[P].ADD; m = tree[p <<1|1].r-tree[p <<1|1].L +1; Tree[p <<1|1].sum + = m * TREE[P].ADD; Tree[p].add =0; }}voidUpdate (node tree[),intPintLintRintVal) {if(L = = Tree[p].l && r = = TREE[P].R) {Tree[p].add + = val;intm = r-l +1; Tree[p].sum + = m * val;return; } pushdown (tree, p);intMid = (tree[p].l + TREE[P].R) >>1;if(R <= Mid) {Update (tree, p <<1, L, R, Val); }Else if(L > Mid) {Update (tree, p <<1|1, L, R, Val); }Else{Update (tree, p <<1, L, Mid, Val); Update (tree, p <<1|1, Mid +1, R, Val); } tree[p].sum = Tree[p <<1].sum + tree[p <<1|1].sum;}intQuery (node tree[),intPintPOS) {if(TREE[P].L = = TREE[P].R) {returnTree[p].sum; } pushdown (tree, p);intMid = (tree[p].l + TREE[P].R) >>1;if(Pos <= mid) {returnQuery (tree, p <<1, POS); }Else{returnQuery (tree, p <<1|1, POS); }}voidGetdepth (intUintFaBOOLFlag) {//1, odd, 2-evenPar[u] = FA; Dep[u] = flag;BOOLOK =1; for(inti = Head[u]; ~i; i = edge[i].nxt) {intv = edge[i].to;if(v = = FA) {Continue; } getdepth (V, u, flag ^1); OK =0; } Is_leaf[u] = OK;}voidDFS1 (intUintFaint&ret) {if(Dep[u]) {Oddl[u] = ++ret; } for(inti = Head[u]; ~i; i = edge[i].nxt) {intv = edge[i].to;if(v = = FA) {Continue; } dfs1 (V, u, ret); }if(Dep[u]) {Oddr[u] = ret; }}voidDFS2 (intUintFaint&ret) {if(!dep[u]) {Evenl[u] = ++ret; } for(inti = Head[u]; ~i; i = edge[i].nxt) {intv = edge[i].to;if(v = = FA) {Continue; } dfs2 (V, u, ret); }if(!dep[u]) {Evenr[u] = ret; }}intMain () {intN, M; while(~scanf("%d%d", &n, &m)) { for(inti =1; I <= N; ++i) {scanf("%d", &arr[i]); }memset(Head,-1,sizeof(head));memset(Is_leaf,0,sizeof(Is_leaf)); tot =0;intU, v; for(inti =1; I <= N-1; ++i) {scanf("%d%d", &u, &v); Addedge (U, v); Addedge (V, u); }intL1 =0, L2 =0; Getdepth (1, -1,1); DFS1 (1, -1, L1); DFS2 (1, -1, L2);//Even for(inti =1; I <= N; ++i) {Subl[i] = inf; Subr[i] =-inf;if(Is_leaf[i]) {Continue; } for(intj = Head[i]; ~j; j = edge[j].nxt) {if(edge[j].to = = Par[i]) {Continue; }if(Dep[i]) {Subl[i] = min (Subl[i], evenl[edge[j].to]); Subr[i] = max (Subr[i], evenr[edge[j].to]); }Else{Subl[i] = min (Subl[i], oddl[edge[j].to]); Subr[i] = max (Subr[i], oddr[edge[j].to]); } } } for(inti =1; I <= N; ++i) {if(!dep[i]) {//EvenNow[evenl[i]] = arr[i]; } }if(L2 >=1) {Build (tree[0],1,1, L2); } for(inti =1; I <= N; ++i) {if(Dep[i]) {Now[oddl[i]] = arr[i]; } }if(L1 >=1) {Build (tree[1],1,1, L1); }intOP, x, y; while(m--) {scanf("%d", &op);if(OP = =1) {scanf("%d%d", &x, &y);if(Dep[x]) {intL = oddl[x];intr = oddr[x]; Update (tree[1],1, L, R, y);if(!is_leaf[x]) {L = subl[x]; r = subr[x]; Update (tree[0],1, L, R,-y); } }Else{intL = evenl[x];intr = evenr[x]; Update (tree[0],1, L, R, y);if(!is_leaf[x]) {L = subl[x]; r = subr[x]; Update (tree[1],1, L, R,-y); } } }Else{scanf("%d", &x);if(Dep[x]) {printf("%d\n", Query (tree[1],1, oddl[x])); }Else{printf("%d\n", Query (tree[0],1, evenl[x])); } } } }return 0;}`

Codeforces Round #225 (Div. 2)---E. propagating tree (timestamp + line segment)