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*, each node *i* having an initial value *a*<sub class="lower-index">*i*</sub>. The root of the tree is node 1.

This tree has a special property: when a value *val* is added to a value of node *i*, the value -*val* is 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 the child of node *i* and so on. Look an example explanation to understand better how it works.

This tree supports two types of queries:
 -  "1 *x* *val*" — *val* is added to the value of node *x*; -  "2 *x*" — print the current value of node *x*. 
In order to help Iahub understand the tree better, you must answer *m* queries of the preceding type.
The first line contains two integers *n* and *m* (1 ≤ *n*, *m* ≤ 200000). The second line contains *n* integers *a*<sub class="lower-index">1</sub>, *a*<sub class="lower-index">2</sub>, ..., *a*<sub class="lower-index">*n*</sub> (1 ≤ *a*<sub class="lower-index">*i*</sub> ≤ 1000). Each of the next *n*–1 lines contains two integers *v*<sub class="lower-index">*i*</sub> and *u*<sub class="lower-index">*i*</sub> (1 ≤ *v*<sub class="lower-index">*i*</sub>, *u*<sub class="lower-index">*i*</sub> ≤ *n*), meaning that there is an edge between nodes *v*<sub class="lower-index">*i*</sub> and *u*<sub class="lower-index">*i*</sub>.

Each of the next *m* lines contains a query in the format described above. It is guaranteed that the following constraints hold for all queries: 1 ≤ *x* ≤ *n*, 1 ≤ *val* ≤ 1000.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("avx2,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

//namespaces
using namespace __gnu_pbds; 
using namespace std;

//MACROS
#define ld long double
#define pb push_back
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ll long long
#define ull unsigned long long 
#define For(i,s,e) for (int i=(s); i<(e); i++)
#define Fod(i,s,e) for (int i=(s); i>=(e); i--)
#define pii pair<ll,ll>
#define f first
#define s second
#define endl "\n"
#define all(container) container.begin(), container.end()
#define mp make_pair
#define int ll
#define len(a) ((int) a.size())
//debug
#define TRACE
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif

//Templates
template <typename T>
using ordered_set =tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <class T> ostream& operator << (ostream &os, const vector<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T> ostream& operator << (ostream &os, const set<T> &v) { for (T i : v) os << i << ' '; return os; }
template <class T, class S> ostream& operator << (ostream &os, const pair<T, S> &v) { os << v.first << ' ' << v.second; return os; }
template <class T, class S> ostream& operator << (ostream &os, const unordered_map<T, S> &v) { for (auto i : v) os << '(' << i.first << "=>" << i.second << ')' << ' '; return os; }

//globals
ll const prime1 = 304933;
ll const prime2 = 15486277;
ll const mod = 1e9+7;
ll const inf = 1e18;
ll const mod2 = 1e17 + 7;
ll const mult = 53;
ll const real_size = 2*1e5 + 8;
ll const size_1d = 2*1e6 + 7;
ll const size_2d = 1e3 + 7;

//functions
ll power(ll x, ll y, ll mod1 = 2e18){ ll ans = 1;x %= mod1;while(y){if(y&1)ans = (x * ans) % mod1;x = (x * x) % mod1;y >>= 1;}return ans;}
ll modInverse(ll a, ll m){ll m0 = m;ll y = 0, x = 1;if (m == 1) return 0;while (a > 1){ ll q = a / m;ll t = m;m = a % m,a = t;t = y;y = x - q * y;x = t;}if(x < 0) x += m0;return x;} 
ll gcdext(ll a,ll b,ll *x = 0, ll *y = 0){if(a == 0){*x = 0;*y = 1;return b;}ll x1,y1;ll gcd1 = gcdext(b%a,a,&x1,&y1);*x = y1 - (b/a)*x1;*y = x1;return gcd1;}
int randomize(){return (rand()%10000);} 

// CODE STARTS HERE
int trav[size_1d];
std::vector<std::vector<int>> v(real_size);
std::vector<int> cost(real_size);
int st[real_size];
int en[real_size],depth[real_size];
int pref[size_1d];
int cur = 0;
void dfs(int a,int b){
	st[a] = cur;
	trav[cur] = a;
	cur++;
	for(auto &m : v[a]){
		if(m != b){
			depth[m] = 1 + depth[a];
			dfs(m,a);
		}
	}
	en[a] = cur;
	trav[cur] = a;
	cur++;
}
int seg[size_1d];
int lazy[size_1d];
int pend[size_1d];
void build(int start,int end,int node){
	if(start == end){
		seg[node] = cost[trav[start]];
		return;
	}
	int mid = (start + end) >> 1;
	build(start,mid,node*2 + 1);
	build(mid + 1,end,node*2 + 2);
	seg[node] = seg[node*2 + 1] + seg[node*2 + 2];
}

void prop(int t,int start,int end){
	int left = t*2 + 1;
	int right = t*2 + 2;
	if(pend[t] != 0){
		int c = pref[end];
		if(start != 0){
			c -= pref[start - 1];
		}
		seg[t] += lazy[t]*c;
		// trace(seg[t],t,start,end,c);
		if(start != end){
			lazy[left] += lazy[t];
			pend[left] = 1;
			lazy[right] += lazy[t];
			pend[right] = 1;
		}
		lazy[t] = 0;
		pend[t] = 0;
	}
}
void update(int qs,int qe,int start,int end,int node,int val){
	prop(node,start,end);
	if(qs <= start && end <= qe){
		lazy[node] += val;
		pend[node] = 1;
		prop(node,start,end);
		return;
	}
	if(start > qe || end < qs){
		return;
	}
	int mid = (start + end) >> 1;
	update(qs,qe,start,mid,node*2 + 1,val);
	update(qs,qe,mid + 1,end,node*2 + 2,val);
	seg[node] = seg[node*2 + 1] + seg[node*2 + 2];
}
int query(int qs,int qe,int start,int end,int node){
	prop(node,start,end);
	if(qs <= start && end <= qe){
		return seg[node];
	}
	if(start > qe || end < qs){
		return 0;
	}
	int mid = (start + end ) >> 1;
	return query(qs,qe,start,mid,node*2 + 1) + query(qs,qe,mid + 1,end,node*2 + 2);
}
signed main(){
  IOS
  int n,m;cin >> n >> m;
  for (int i = 0; i < n; ++i)
  {
  	cin >> cost[i + 1];
  }
  for (int i = 0; i < n-1; ++i)
  {
  	int x,y;cin >> x >> y;
  	v[x].pb(y);
  	v[y].pb(x);
  }
  dfs(1,0);
  for (int i = 0; i < cur; ++i)
  {
  	if(i == 0){
  		pref[i] = (depth[trav[i]]%2 ? 1 : -1);
  	}	
  	else{
  		pref[i] = (depth[trav[i]]%2 ? 1 : -1) + pref[i-1];
  	}
  }
  build(0,cur,0);
  // for (int i = 0; i < 20; ++i)
  // {
  // 	cout << trav[i] << ":" << depth[trav[i]] << " ";
  // }
  // cout << endl;
  while(m--){
  	int t;cin >> t;
  	if(t == 1){
  		int x,val;cin >> x >> val;
  		if(depth[x]%2 == 0){
  			update(st[x],en[x],0,cur,0,-val);
  		}
  		else{
  			update(st[x],en[x],0,cur,0,val);
  		}
  	}
  	else{
  		int x;cin >> x;
  		int ans = query(st[x],st[x],0,cur,0);
  		cout << ans << endl;
  	}
  }
  return 0;
}