/*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

*/
/*

**************************
*						 *
* AUTHOR :: knight_coder *
*						 *
**************************

*/
#include<bits/stdc++.h>
#define lld          long long int
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<lld,lld>
#define msi         map<string,lld>
#define mis         map<lld, string>
#define mpi         map<pair<lld ,lld >,lld >
#define pii         pair<lld,lld>
#define vi          vector<int>
#define vpi 		vector<pii>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (lld)x.size()
#define hell        1000000007
#define rrep(i,m,n)	for(lld i=m;i>=n;i--)
#define rep(i,m,n)	for(lld i=m;i<n;i++)
#define lbnd        lower_bound
#define ubnd        upper_bound
#define bs          binary_search
#define mp          make_pair
#define what_is(x)  cerr << #x << " is " << x << endl;
#define pr(x) 		cout<< x << " ";
#define pre(x)		cout<< x << endl ;
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;
//change null_type to get ordered_map
#define N  200005
int tme[2];
int b[N],a[N];
bool vis[N];
int ht[N];
int intt[N][2],outt[N][2];
int c[N];
vi v[N];
void inii(){
	rep(i,0,N){
		a[i]=0,b[i]=0;
		vis[i]=false;
		ht[i]=0;
	}
}
void dfs(int node,int dep){
	vis[node]=true;
	ht[node]=dep;
	if(dep%2){
		a[tme[1]]=c[node];
	}
	else{
		b[tme[0]]=c[node];
	}
	rep(i,0,2){
		intt[node][i]=tme[i];
	}
	tme[dep%2]++;
	for(auto i:v[node]){
		if(!vis[i]){
			dfs(i,dep+1);
		}
	}
	rep(i,0,2){
		outt[node][i]=tme[i];
	}
}
vi seg[2],lazy[2];
void build(int node,int start,int end,int flag){
    if(start==end){
    	if(flag)
	        seg[flag][node]=a[start];
    	else
    		seg[flag][node]=b[start];
        return;
    }
    int mid=(start+end)>>1;
    build(node<<1,start,mid,flag);
    build(node<<1|1,mid+1,end,flag);
    seg[flag][node]=seg[flag][node<<1]+seg[flag][node<<1|1];
}
void update(int node,int start,int end,int l,int r,int val,int flag){
    if(lazy[flag][node]!=0){
        seg[flag][node]+=(end-start+1)*lazy[flag][node];
        if(start!=end){
            lazy[flag][node<<1]+=lazy[flag][node];
            lazy[flag][node<<1|1]+=lazy[flag][node];
        }
        lazy[flag][node]=0;
    }
    if(start>end || start>r || end<l) return;
    if(l<=start && end<=r){
        seg[flag][node]+=(end-start+1)*val;
        if(start!=end){
            lazy[flag][node<<1]+=val;
            lazy[flag][node<<1|1]+=val;
        }
        return;
    }
    int mid=(start+end)>>1;
    update(node<<1,start,mid,l,r,val,flag);
    update(node<<1|1,mid+1,end,l,r,val,flag);
    seg[flag][node]=seg[flag][node<<1]+seg[flag][node<<1|1];
}
lld query(int node,int start,int end,int l,int r,int flag){
    if(start>end || start>r || end<l) return 0;
    if(lazy[flag][node]!=0){
        seg[flag][node]+=(end-start+1)*lazy[flag][node];
        if(start!=end){
            lazy[flag][node<<1]+=lazy[flag][node];
            lazy[flag][node<<1|1]+=lazy[flag][node];
        }
        lazy[flag][node]=0;
    }
    if(start>=l && end<=r) return seg[flag][node];
    int mid=(start+end)>>1;
    lld q1=query(node<<1,start,mid,l,r,flag);
    lld q2=query(node<<1|1,mid+1,end,l,r,flag);
    return q1+q2;
}
void solve()
{
	inii();
	int n,m;
	cin >> n >> m;
	rep(i,1,n+1){
		cin >> c[i];
	}
	rep(i,1,n){
		lld x,y;
		cin >> x >> y;
		v[x].pb(y),v[y].pb(x);
	}
	dfs(1,0);
	rep(i,0,2){
		seg[i].resize(4*tme[i]+4);
		lazy[i].resize(4*tme[i]+4);
	}
	rep(i,0,2){
		build(1,0,tme[i]-1,i);
	}
	rep(i,0,m){
		int ty;
		cin >> ty;
		if(ty==1){
			int x,val;
			cin >> x >> val;
			int r=ht[x]%2;
			if(intt[x][r]<=outt[x][r]-1)
				update(1,0,tme[r]-1,intt[x][r],outt[x][r]-1,val,r);
			if(intt[x][1^r]<=outt[x][1^r]-1)
				update(1,0,tme[r^1]-1,intt[x][1^r],outt[x][1^r]-1,-val,1^r);
		}
		else{
			int x;
			cin >> x;
			int r=ht[x]%2;
			lld ans;
			if(r){
				ans=query(1,0,tme[1]-1,intt[x][1],intt[x][1],1);
			}
			else{
				ans=query(1,0,tme[0]-1,intt[x][0],intt[x][0],0);
			}
			cout << ans << endl;
		}
	}
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int tests=1;
	//cin>>tests;
	while(tests--)
	{
		solve();
	}
}


#include <bits/stdc++.h>

using namespace std;

const int MAXN=2e5+10;

int n, m, t, num[MAXN], h[MAXN], d[MAXN], in[MAXN], out[MAXN];
int o[4*MAXN], p[4*MAXN];
int lo[4*MAXN], lp[4*MAXN];
vector<int> graph[MAXN];

void dfs(int u, int f){
	d[++t]=u;
	in[u]=t;
	out[u]=t;
	h[u]=h[f]+1;
	for(auto v: graph[u]){
		if(v!=f){
			dfs(v, u);
			out[u]=max(out[u], out[v]);
		}

	}
}

void build(int u, int l, int r){

	if(l==r){
		if(h[d[l]]%2==1){

			o[u]=num[d[l]];
		}else{

			p[u]=num[d[l]];
		}
		return;
	}

	int mid=(l+r)/2;
	build(2*u, l, mid); build(2*u+1, mid+1, r);

	o[u]=o[2*u]+o[2*u+1];
	p[u]=p[2*u]+p[2*u+1];
}

void upd(int u, int l, int r, int a, int b, int val){
	if(lo[u]!=0){
		if(l!=r){
			lo[2*u]+=lo[u];
			lo[2*u+1]+=lo[u];
		}

		o[u]+=lo[u]*(r-l+1);
		lo[u]=0;
	}
	if(lp[u]!=0){
		if(l!=r){
			lp[2*u]+=lp[u];
			lp[2*u+1]+=lp[u];
		}

		p[u]+=lp[u]*(r-l+1);
		lp[u]=0;
	}
	if(l>b || r<a) return;

	if(a<=l && r<=b){

		if(r!=l){
			lo[2*u]+=val;
			lo[2*u+1]+=val;
			lp[2*u]+=(-val);
			lp[2*u+1]+=(-val);
		}
		o[u]+=val*(r-l+1);
		p[u]+=(-val)*(r-l+1);
		return;
	}

	int mid=(l+r)/2;

	upd(2*u, l, mid, a, b, val); upd(2*u+1, mid+1, r, a, b, val);
	o[u]=o[2*u]+o[2*u+1];
	p[u]=p[2*u]+p[2*u+1];
}

int get(int u, int l, int r, int i){

	if(lo[u]!=0){
		if(l!=r){
			lo[2*u]+=lo[u];
			lo[2*u+1]+=lo[u];
		}

		o[u]+=lo[u]*(r-l+1);
		lo[u]=0;
	}
	if(lp[u]!=0){
		if(l!=r){
			lp[2*u]+=lp[u];
			lp[2*u+1]+=lp[u];
		}

		p[u]+=lp[u]*(r-l+1);
		lp[u]=0;
	}

	if(l==r){
		if(h[d[l]]%2==1){
			return o[u];
		}else{
			return p[u];
		}
	}

	int mid=(l+r)/2;

	if(i<=mid) return get(2*u, l, mid, i);
	else return get(2*u+1, mid+1, r, i);
}

int main(){

	scanf("%d%d", &n, &m);

	for(int i=1;i<=n;++i){

		scanf("%d", &num[i]);
	}

	for(int i=1;i<n;++i){

		int u, v;
		scanf("%d%d", &u, &v);

		graph[u].push_back(v);
		graph[v].push_back(u);
	}

	dfs(1, 1);
	build(1, 1, t);
	for(int i=0;i<m;++i){

		int id;
		scanf("%d", &id);
		if(id==1){
			int x, val;
			scanf("%d%d", &x, &val);
			if(h[x]%2==0) val=-val;

			upd(1, 1, t, in[x], out[x], val);
		}else{
			int x;
			scanf("%d", &x);

			printf("%d\n", get(1, 1, t, in[x]));
		}
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define pl pair<ll,ll>
#define vl vector<ll>
const ll N = 2e5 + 3;
ll a[N], st[N], fin[N], depth[N], bit[N], n, m, tme = 1;
vector<vl> G(N);

void fastio()
{
	ios_base::sync_with_stdio(false);cin.tie(NULL);
	cout<<fixed<<setprecision(10);
}

void dfs(ll node, ll par)
{
	st[node] = tme++;
	depth[node] = depth[par] + 1;
	for(auto child: G[node])
	{
		if(child != par)
		{
			dfs(child, node);
		}
	}
	fin[node] = tme - 1;
}

void update(ll idx, ll val)
{
	for(ll i = idx; i <= n; i += (i & -i))
	{
		bit[i] += val;
	}
}

ll get(ll idx)
{
	ll sum = 0;
	for(ll i = idx; i; i -= (i & -i))
	{
		sum += bit[i];
	}
	return sum;
}

int main()
{
	fastio();
	cin>>n>>m;
	for(ll i = 1; i <= n; i++)
	{
		cin>>a[i];
	}
	for(ll i = 1; i < n; i++)
	{
		ll x, y;
		cin>>x>>y;
		G[x].pb(y);
		G[y].pb(x);
	}
	dfs(1, 0);
	for(ll i = 1; i <= m; i++)
	{
		ll typ, x;
		cin>>typ>>x;
		if(typ == 1)
		{
			ll val;
			cin>>val;
			if(depth[x]&1LL)
			{
				update(st[x], -val);
				update(fin[x] + 1, val);
			}
			else
			{
				update(st[x], val);
				update(fin[x] + 1, -val);
			}
		}
		else
		{
			ll ans;
			if(depth[x]&1LL)
			{
				ans = a[x] - get(st[x]);
			}
			else
			{
				ans = a[x] + get(st[x]);
			}
			cout<<ans<<"\n";
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#define endl '\n'
using namespace std;
typedef long long int ll ;
const ll mod =1000000007;
const ll MAX=100008;
vector<ll> v[200005];
ll in[200005];
ll out[200005];
ll arr[200005];
ll value[200005];
ll level[200005];
int vis[200005];
ll timer=0;
struct node
{
    ll odd,even;
};

void dfs(ll node)
{
    vis[node]=1;
    timer++;
    in[node]=timer;
    arr[timer]=node;
    for(int i=0;i<v[node].size();i++){
        if(vis[v[node][i]]==0) { level[v[node][i]]=level[node]+1; dfs(v[node][i]); }
    }
    out[node]=timer;
}
struct node lazy[900009];

void initialize() { for(int i=0;i<900009;i++) {lazy[i].odd=0; lazy[i].even=0; }  }

ll ans=0;

void query(ll start,ll end,ll node, ll idx,ll lev)
{
		ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>idx || idx >end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}

	else if(start==end && idx==end) {
	    if(lev&1) ans+=lazy[node].odd;
	    else ans+=lazy[node].even;
	}
	else{
		query(start,mid,2*node,idx, lev); //cout<<"child1 "<<child1<<endl;
		query(mid+1,end,(2*node)+1,idx,lev); //cout<<"child2 "<<child2<<endl;
	}
}

void update(ll start,ll end,ll node,ll l,ll r,ll val,ll lev)		//update in range of l to r
{
	ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>r || l>end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}
	else if(l<=start && r>=end) {
		if(lev%2==0) {lazy[node].even+=val; lazy[node].odd-=val; }
		else {       lazy[node].even-=val; lazy[node].odd+=val; }
		return ;
	}
	else{
		update(start,mid,2*node,l,r,val,lev);
		update(mid+1,end,(2*node)+1,l,r,val,lev);
	}
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>value[i];
    for(int i=1;i<=n-1;i++){
        ll a,b; cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
     level[1]=1;
    dfs(1);
    initialize();
    for(int i=1;i<=n;i++)  arr[in[i]]=value[i];
    // for(int i=1;i<=n;i++) cout<<arr[i]<<" ";
    // cout<<endl;

    while(q--){
        int ch ; cin>>ch;
        if(ch==1){
            ll node, x; cin>>node>>x;
            ll idx=in[node];
            update(1LL,n,1LL,in[node],out[node],x,level[node]);
        }
        else {
            ll node; cin>>node;
            ans=value[node];
            query(1,n,1,in[node],level[node]);
            cout<<ans<<endl;
        }
    }
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#define endl '\n'
using namespace std;
typedef long long int ll ;
const ll mod =1000000007;
const ll MAX=100008;
vector<ll> v[200005];
ll in[200005];
ll out[200005];
ll value[200005];
ll level[200005];
int vis[200005];
ll timer=0;
struct node
{
    ll odd,even;
};

void dfs(ll node)
{
    vis[node]=1;
    timer++;
    in[node]=timer;
    for(int i=0;i<v[node].size();i++){
        if(vis[v[node][i]]==0) { level[v[node][i]]=level[node]+1; dfs(v[node][i]); }
    }
    out[node]=timer;
}
struct node lazy[900009];

void initialize() { for(int i=0;i<900009;i++) {lazy[i].odd=0; lazy[i].even=0; }  }

ll ans=0;

void query(ll start,ll end,ll node, ll idx,ll lev)
{
		ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>idx || idx >end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}

	else if(start==end && idx==end) {
	    if(lev&1) ans+=lazy[node].odd;
	    else ans+=lazy[node].even;
	}
	else{
		query(start,mid,2*node,idx, lev); //cout<<"child1 "<<child1<<endl;
		query(mid+1,end,(2*node)+1,idx,lev); //cout<<"child2 "<<child2<<endl;
	}
}

void update(ll start,ll end,ll node,ll l,ll r,ll val,ll lev)		//update in range of l to r
{
	ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>r || l>end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}
	else if(l<=start && r>=end) {
		if(lev%2==0) {lazy[node].even+=val; lazy[node].odd-=val; }
		else {       lazy[node].even-=val; lazy[node].odd+=val; }
		return ;
	}
	else{
		update(start,mid,2*node,l,r,val,lev);
		update(mid+1,end,(2*node)+1,l,r,val,lev);
	}
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>value[i];
    for(int i=1;i<=n-1;i++){
        ll a,b; cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
     level[1]=1;
    dfs(1);
    initialize();

    while(q--){
        int ch ; cin>>ch;
        if(ch==1){
            ll node, x; cin>>node>>x;
            ll idx=in[node];
            update(1LL,n,1LL,in[node],out[node],x,level[node]);
        }
        else {
            ll node; cin>>node;
            ans=value[node];
            query(1,n,1,in[node],level[node]);
            cout<<ans<<endl;
        }
    }
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#define endl '\n'
using namespace std;
typedef long long int ll ;
const ll mod =1000000007;
const ll MAX=100008;
vector<ll> v[200005];
ll in[200005];
ll out[200005];
ll arr[200005];
ll value[200005];
ll level[200005];
int vis[200005];
ll timer=0;
struct node
{
    ll odd,even;
};

void dfs(ll node)
{
    vis[node]=1;
    timer++;
    in[node]=timer;
    arr[timer]=node;
    for(int i=0;i<v[node].size();i++){
        if(vis[v[node][i]]==0) { level[v[node][i]]=level[node]+1; dfs(v[node][i]); }
    }
    out[node]=timer;
}
struct node lazy[900009];

void initialize() { for(int i=0;i<900009;i++) {lazy[i].odd=0; lazy[i].even=0; }  }

ll ans=0;

void query(ll start,ll end,ll node, ll idx,ll lev)
{
		ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>idx || idx >end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}

	else if(start==end && idx==end) {
	    if(lev&1) ans+=lazy[node].odd;
	    else ans+=lazy[node].even;
	}
	else{
		query(start,mid,2*node,idx, lev); //cout<<"child1 "<<child1<<endl;
		query(mid+1,end,(2*node)+1,idx,lev); //cout<<"child2 "<<child2<<endl;
	}
}

void update(ll start,ll end,ll node,ll l,ll r,ll val,ll lev)		//update in range of l to r
{
	ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>r || l>end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}
	else if(l<=start && r>=end) {
		if(lev%2==0) {lazy[node].even+=val; lazy[node].odd-=val; }
		else {       lazy[node].even-=val; lazy[node].odd+=val; }
		return ;
	}
	else{
		update(start,mid,2*node,l,r,val,lev);
		update(mid+1,end,(2*node)+1,l,r,val,lev);
	}
}

int main()
{
    ll n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>value[i];
    for(int i=1;i<=n-1;i++){
        ll a,b; cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
     level[1]=1;
    dfs(1);
    initialize();
    for(int i=1;i<=n;i++)  arr[in[i]]=value[i];
    // for(int i=1;i<=n;i++) cout<<arr[i]<<" ";
    // cout<<endl;

    while(q--){
        int ch ; cin>>ch;
        if(ch==1){
            ll node, x; cin>>node>>x;
            ll idx=in[node];
            update(1LL,n,1LL,in[node],out[node],x,level[node]);
        }
        else {
            ll node; cin>>node;
            ans=value[node];
            query(1,n,1,in[node],level[node]);
            cout<<ans<<endl;
        }
    }
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#define endl '\n'
using namespace std;
typedef long long int ll ;
const ll mod =1000000007;
const ll MAX=100008;
vector<ll> v[100005];
ll in[200005];
ll out[200005];
ll arr[200005];
ll value[200005];
ll level[200005];
int vis[200005];
ll timer=0;
struct node
{
    ll odd,even;
};

void dfs(ll node)
{
    vis[node]=1;
    timer++;
    in[node]=timer;
    arr[timer]=node;
    for(int i=0;i<v[node].size();i++){
        if(vis[v[node][i]]==0) { level[v[node][i]]=level[node]+1; dfs(v[node][i]); }
    }
    out[node]=timer;
}
struct node lazy[900009];

void initialize() { for(int i=0;i<900009;i++) {lazy[i].odd=0; lazy[i].even=0; }  }

ll ans=0;

void query(ll start,ll end,ll node, ll idx,ll lev)
{
		ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>idx || idx >end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}

	else if(start==end && idx==end) {
	    if(lev&1) ans+=lazy[node].odd;
	    else ans+=lazy[node].even;
	}
	else{
		query(start,mid,2*node,idx, lev); //cout<<"child1 "<<child1<<endl;
		query(mid+1,end,(2*node)+1,idx,lev); //cout<<"child2 "<<child2<<endl;
	}
}

void update(ll start,ll end,ll node,ll l,ll r,ll val,ll lev)		//update in range of l to r
{
	ll mid=(start+end)>>1;
	if( lazy[node].even!=0   && lazy[node].odd!=0 && start!=end) {

		lazy[2*node].even+=lazy[node].even;
		lazy[2*node+1].even+=lazy[node].even;
		lazy[2*node].odd+=lazy[node].odd;
		lazy[2*node+1].odd+=lazy[node].odd;
		lazy[node].even=0; lazy[node].odd=0;
	}

	if(start>r || l>end) {				//no overlap case  return that value which does not affect the ans
		return ;
	}
	else if(l<=start && r>=end) {
		if(lev%2==0) {lazy[node].even+=val; lazy[node].odd-=val; }
		else {       lazy[node].even-=val; lazy[node].odd+=val; }
		return ;
	}
	else{
		update(start,mid,2*node,l,r,val,lev);
		update(mid+1,end,(2*node)+1,l,r,val,lev);
	}
}

int main()
{
    ll n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++) cin>>value[i];
    for(int i=1;i<=n-1;i++){
        ll a,b; cin>>a>>b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
     level[1]=1;
    dfs(1);
    initialize();
    for(int i=1;i<=n;i++)  arr[in[i]]=value[i];
    // for(int i=1;i<=n;i++) cout<<arr[i]<<" ";
    // cout<<endl;

    while(q--){
        int ch ; cin>>ch;
        if(ch==1){
            ll node, x; cin>>node>>x;
            ll idx=in[node];
            update(1LL,n,1LL,in[node],out[node],x,level[node]);
        }
        else {
            ll node; cin>>node;
            ans=value[node];
            query(1,n,1,in[node],level[node]);
            cout<<ans<<endl;
        }
    }
}


/**
 *  author: Duarte Nobrega
 *  created: 03.06.2020
**/

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;

vector< vector<int> > g (N);

int cost [N], in [N], out [N], depth[N], Time = 0;

void dfs (int node = 0, int p = 0) {
  in[node] = ++Time;
  for (auto to : g[node]) {
    if (to != p) {
      depth[to] = depth[node] + 1;
      dfs (to, node);
    }
  }
  out[node] = Time;
}

struct FenwickTree {
  const int L;
  vector<int> bit;
  FenwickTree (int n) : L (n + 5) {
    bit.clear();
    bit.resize(L);
  }
  void update (int idx, int delta) {
    for (; idx < L; idx += idx & (- idx) ) {
      bit[idx] += delta;
    }
  }
  void range_update (int lo, int hi, int delta) {
    update (lo, + delta);
    update (hi + 1, - delta);
  }
  int query (int idx) {
    int res = 0;
    for (; idx > 0; idx -= idx & (- idx)) {
      res += bit[idx];
    }
    return res;
  }
};

int main () {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) cin >> cost[i];
  for (int i = 0; i < n - 1; i++) {
    int st, et;
    cin >> st >> et;
    --st; --et;
    g[st].emplace_back(et);
    g[et].emplace_back(st);
  }
  dfs ();
  FenwickTree odd (N), even (N);
  while (q--) {
    int task;
    cin >> task;
    if (task == 1) {
      int where, delta;
      cin >> where >> delta;
      --where;
      int st = in[where];
      int et = out[where];
      even.range_update (st, et, - delta);
      odd.range_update (st, et, - delta);
      if (depth[where] & 1) odd.range_update (st, et, 2 * delta);
      else even.range_update (st, et, 2 * delta);
    } else {
      int where;
      cin >> where;
      --where;
      int idx = in[where];
      cout << cost[where] + (depth[where] & 1 ? odd.query(idx) : even.query(idx) ) << '\n';
    }
  }
  return 0;
}


/**
 *  author: Duarte Nobrega
 *  created: 02.06.2020
**/

#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 5;

vector< vector<int> > g (N);

int cost [N], in [N], out [N], depth[N], Time = 0;

void dfs (int node = 0, int p = 0) {
  in[node] = ++Time;
  for (auto to : g[node]) {
    if (to != p) {
      depth[to] = depth[node] + 1;
      dfs (to, node);
    }
  }
  out[node] = Time;
}

struct FenwickTree {
  const int L;
  vector<int> bit;
  FenwickTree (int n) : L (n + 5) {
    bit.clear();
    bit.resize(L);
  }
  void update (int idx, int delta) {
    for (; idx < L; idx += idx & (- idx) ) {
      bit[idx] += delta;
    }
  }
  void range_update (int lo, int hi, int delta) {
    update (lo, + delta);
    update (hi + 1, - delta);
  }
  int query (int idx) {
    int res = 0;
    for (; idx > 0; idx -= idx & (- idx)) {
      res += bit[idx];
    }
    return res;
  }
};

int main () {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  for (int i = 0; i < n; i++) cin >> cost[i];
  for (int i = 0; i < n - 1; i++) {
    int st, et;
    cin >> st >> et;
    --st; --et;
    g[st].emplace_back(et);
    g[et].emplace_back(st);
  }
  dfs ();
  FenwickTree odd (N), even (N), sub (N);
  while (q--) {
    int task;
    cin >> task;
    if (task == 1) {
      int where, delta;
      cin >> where >> delta;
      --where;
      int st = in[where];
      int et = out[where];
      sub.range_update (st, et, - delta);
      if (depth[where] & 1) odd.range_update (st, et, 2 * delta);
      else even.range_update (st, et, 2 * delta);
    } else {
      int where;
      cin >> where;
      --where;
      int idx = in[where];
      cout << cost[where] + sub.query (idx) + (depth[where] & 1 ? odd.query(idx) : even.query(idx) ) << '\n';
    }
  }
  return 0;
}


#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>

//using namespace __gnu_pbds;

#define N 1000000

using namespace std;

typedef long long ll;
typedef long double ld;

const ll INF = 1e18, MOD = 1e9 + 7, MOD2 = 1e6 + 3;
const int M = 1e6;

ll d[N], s[N];
int tin[N], tout[N], a[N], h[N], n, m, timer;

vector <int> g[N];
vector < pair <int, int> > st;

void dfs (int x, int p) {
	if (p != -1) h[x] = h[p] + 1;
	tin[x] = ++timer;

	for (int to : g[x])
		if (to != p) dfs (to, x);
	tout[x] = ++timer;
}

inline bool parent (int a, int b) {
	return tin[a] <= tin[b] && tout[b] <= tout[a];
}

void recalc (int x, int p) {
	d[x] = s[x];
	if (p != -1) d[x] -= d[p];

	for (int to : g[x])
		if (to != p) recalc (to, x);
}

int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	for (int i = 0; i < n - 1; i++) {
		int a, b;
		cin >> a >> b;
		a--, b--;

		g[a].push_back (b);
		g[b].push_back (a);
	}

	dfs (0, -1);

	for (int i = 0; i < m; i++) {
		int t, x, val;

		cin >> t;

		if (t == 1) {
			cin >> x >> val;
			x--;

			st.push_back ({x, val});

			s[x] += val;

			if (st.size () == 500) {
				st.clear ();
				recalc (0, -1);
			}
		} else {
			cin >> x; x--;
			ll ans = d[x] + a[x];

			for (auto a : st) {
				if (parent (a.first, x)) {
					ans += ((h[x] & 1) == (h[a.first] & 1) ? a.second : -a.second);
				}
			}

			cout << ans << '\n';
		}
	}
}


#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>

//using namespace __gnu_pbds;

#define N 1000000

using namespace std;

typedef long long ll;
typedef long double ld;

const ll INF = 1e18, MOD = 1e9 + 7, MOD2 = 1e6 + 3;
const int M = 1e6;

ll d[N], s[N];
int tin[N], tout[N], a[N], h[N], n, m, timer;
int p[N];

vector <int> g[N];
vector < pair <int, int> > st;

void dfs (int x, int up) {
	p[x] = up;
	if (up != -1) h[x] = h[up] + 1;
	tin[x] = ++timer;

	for (int to : g[x])
		if (to != up) dfs (to, x);

	tout[x] = timer;
}

struct BIT {
	ll t[N];

	void update (int x, ll d) {
		for (; x < n; x = (x | (x + 1)))
			t[x] += d;
	}

	ll get (int r) {
		ll sum = 0;

		for (; r >= 0; r = (r & (r + 1)) - 1)
			sum += (ll) t[r];

		return sum;
	}

	ll get (int l, int r) { return get (r) - get (l - 1); }
} t;

int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	for (int i = 0; i < n - 1; i++) {
		int a, b;
		cin >> a >> b;
		a--, b--;

		g[a].push_back (b);
		g[b].push_back (a);
	}

	dfs (0, -1);

	for (int i = 0; i < m; i++) {
		int c, x, val;

		cin >> c;

		if (c == 1) {
			cin >> x >> val;
			x--;

			if (h[x] & 1) val = -val;

			t.update (tin[x], val);
			t.update (tout[x] + 1, -val);

		} else {
			cin >> x; x--;
			ll ans = t.get (tin[x]);
			if (h[x] & 1) ans = a[x] - ans;
			else ans = a[x] + ans;

			cout << ans << '\n';
		}
	}
}


#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>

//using namespace __gnu_pbds;

#define N 1000000

using namespace std;

typedef long long ll;
typedef long double ld;

const ll INF = 1e18, MOD = 1e9 + 7, MOD2 = 1e6 + 3;
const int M = 1e6;

ll d[N], s[N];
int tin[N], tout[N], a[N], h[N], n, m, timer;
int p[N];

vector <int> g[N];
vector < pair <int, int> > st;

void dfs (int x, int up) {
	p[x] = up;
	if (up != -1) h[x] = h[up] + 1;
	tin[x] = ++timer;

	for (int to : g[x])
		if (to != up) dfs (to, x);
	tout[x] = ++timer;
}

inline bool parent (int a, int b) {
	return tin[a] <= tin[b] && tout[b] <= tout[a];
}

void recalc (int x) {
	queue <int> q;
	q.push (0);

	while (!q.empty ()) {
		int x = q.front();
		q.pop ();

		d[x] = s[x] - (x ? d[p[x]] : 0);

		for (int to : g[x])
			if (to != p[x]) q.push (to);
	}
}

int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	for (int i = 0; i < n - 1; i++) {
		int a, b;
		cin >> a >> b;
		a--, b--;

		g[a].push_back (b);
		g[b].push_back (a);
	}

	dfs (0, -1);

	for (int i = 0; i < m; i++) {
		int t, x, val;

		cin >> t;

		if (t == 1) {
			cin >> x >> val;
			x--;

			st.push_back ({x, val});

			s[x] += val;

			if (st.size () == 500) {
				st.clear ();
				recalc (0);
			}
		} else {
			cin >> x; x--;
			ll ans = d[x] + a[x];

			for (auto a : st) {
				if (parent (a.first, x)) {
					ans += ((h[x] & 1) == (h[a.first] & 1) ? a.second : -a.second);
				}
			}

			cout << ans << '\n';
		}
	}
}


#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>

//using namespace __gnu_pbds;

#define N 1000000

using namespace std;

typedef long long ll;
typedef long double ld;

const ll INF = 1e18, MOD = 1e9 + 7, MOD2 = 1e6 + 3;
const int M = 1e6;

int tin[N], tout[N], a[N], n, m, timer;
int h[N];

vector <int> g[N];

void dfs (int x, int up) {
	if (up != -1) h[x] = h[up] + 1;
	tin[x] = ++timer;

	for (int to : g[x])
		if (to != up) dfs (to, x);

	tout[x] = timer;
}

struct BIT {
	ll t[N];

	void update (int x, ll d) {
		for (; x <= n; x = (x | (x + 1)))
			t[x] += d;
	}

	ll get (int r) {
		ll sum = 0;

		for (; r >= 0; r = (r & (r + 1)) - 1)
			sum += (ll) t[r];

		return sum;
	}

	ll get (int l, int r) { return get (r) - get (l - 1); }
} t;

int main () {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	for (int i = 0; i < n - 1; i++) {
		int a, b;
		cin >> a >> b;
		a--, b--;

		g[a].push_back (b);
		g[b].push_back (a);
	}

	dfs (0, -1);

	for (int i = 0; i < m; i++) {
		int c, x, val;

		cin >> c;

		if (c == 1) {
			cin >> x >> val;
			x--;

			if (h[x] & 1) val = -val;

			t.update (tin[x], val);
			t.update (tout[x] + 1, -val);

		} else {
			cin >> x; x--;
			ll ans = t.get (tin[x]);
			if (h[x] & 1) ans = a[x] - ans;
			else ans = a[x] + ans;

			cout << ans << '\n';
		}
	}
}


#include <bits/stdc++.h>
using namespace std;
#define SC               scanf
#define PF               printf
#define ull              unsigned long long
#define ld               long double
#define D                double
#define F                first
#define S                second
#define pb               push_back
#define sort_a(a)        sort(a.begin(),a.end());
#define sort_d(a)        sort(a.rbegin(),a.rend());
#define READ(f)          freopen(f, "r", stdin)
#define WRITE(f)         freopen(f, "w", stdout)=..
#define rev(s)           reverse(s.begin(),s.end())
#define Heart              ios_base :: sync_with_stdio(false); cin.tie(NULL);
#define ll long long
typedef pair<int,int>                   PII;
#define MX 200005
vector < int > edge[MX] ;
int n, q, u, v, id, chk,val[MX], st[MX], en[MX], level[MX] ;
void DFS(int x, int par)
{

    st[x] = ++id ;
    for(auto child : edge[x])
    {
        if(child == par)
        {
            continue ;
        }
        else
        {
            level[child] = level[x] + 1 ;
            DFS(child, x) ;
        }
    }
    en[x] =  id ;
}
template<class V, int lm> class BIT
{
public:
    V bit[1 << lm];

    V query(int idx)
    {
        V sum = 0;
        idx++;
        while(idx)
        {
            sum += bit[idx - 1] ;
            idx -= idx & -idx ;
        }
        return sum;
    }
    void update(int idx, V val)
    {
        idx++;
        while(idx <= (1 << lm))
        {
            bit[idx - 1] += val ;
            idx += idx & -idx ;
        }
    }
};
BIT<int,20> bit[2];
void solve()
{
    cin >> n >> q ;
    for(int i = 0 ; i < n ; i++)
    {
        cin >> val[i] ;
    }
    for(int i = 0 ; i < n - 1 ; i++)
    {
        cin >> u  >> v  ;
        edge[u - 1].pb(v - 1) ;
        edge[v - 1].pb(u - 1) ;
    }
    DFS(0, -1) ;
    //for(int i = 0 ; i < n ; i++)cout << st[i] << " " << en[i] << " " << level[i]<< endl ;
    while(q--)
    {
        cin >> chk ;
        if(chk == 1)
        {
            cin >> u >> v ;

            bit[level[u - 1] & 1].update(st[u - 1], v) ;
            bit[level[u - 1] & 1].update(en[u - 1] + 1, -v) ;
        }
        else
        {
            cin >> u ;
            int xtra = bit[0].query(st[u - 1]) - bit[1].query(st[u - 1]) ;
            if(level[u - 1] & 1)
            {
                xtra = -xtra ;
            }
            cout << val[u - 1] + xtra << endl ;
        }
    }
}
int main()
{
    Heart
    //  READ("0test.txt");
    // WRITE("");
    solve() ;

}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define PII pair <int,int>

///**
template < typename F, typename S >
ostream& operator << ( ostream& os, const pair< F, S > & p )
{
    return os << "(" << p.first << ", " << p.second << ")";
}

template < typename T >
ostream &operator << ( ostream & os, const vector< T > &v )
{
    os << "{";
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        if ( it != v.begin() )
            os << ", ";
        os << *it;
    }
    return os << "}";
}

template < typename T >
ostream &operator << ( ostream & os, const set< T > &v )
{
    os << "[";
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        if ( it != v.begin())
            os << ", ";
        os << *it;
    }
    return os << "]";
}

template < typename F, typename S >
ostream &operator << ( ostream & os, const map< F, S > &v )
{
    os << "[";
    for (auto it = v.begin(); it != v.end(); ++it)
    {
        if ( it != v.begin() )
            os << ", ";
        os << it -> first << " = " << it -> second ;
    }
    return os << "]";
}

#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)

clock_t tStart = clock();
#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)

void faltu ()
{
    cerr << endl;
}

template <typename T>
void faltu( T a[], int n )
{
    for (int i = 0; i < n; ++i)
        cerr << a[i] << ' ';
    cerr << endl;
}

template <typename T, typename ... hello>
void faltu( T arg, const hello &... rest)
{
    cerr << arg << ' ';
    faltu(rest...);
}

/// TEMPLATE ----------------------------------------------------------------------->>>>>>

PII Time[200005];
ll tree[525000];
int num[200005],coeff[200005],fns = 1;
vector<int>edges[200005];

void dfs(int s,int k)
{
    if(coeff[s]!=0)
        return;
    coeff[s] = k ;
    Time[s].first = fns;
// dbg(s,Time[s].first);
    int i,t;
    for( auto u : edges[s])
    {
        dfs(u,-k); /// even->odd->even
    }
    Time[s].second = fns;
// dbg(s,Time[s].second);
    fns++;

}

void propagate(int pos)
{
    tree[2*pos] += tree[pos];
    tree[2*pos+1] += tree[pos];
    tree[pos] = 0;
}

void update (int pos,int L,int R,int l,int r,int val)
{
    if (L>r || l>R)
        return;
    if (L>=l && R<=r)
    {
        tree[pos]+=val;
        return;
    }

    if (tree[pos]!=0)
        propagate(pos);

    int x=pos*2,mid=(L+R)/2;
    update (x,L,mid,l,r,val);
    update (x+1,mid+1,R,l,r,val);
}

ll query (int pos,int L,int R,int k)
{
    if (L>k || k>R)
        return 0;
    if (L==R)
        return tree[pos];

    if (tree[pos]!=0)
        propagate(pos);

    int x=pos*2,mid=(L+R)/2;
    ll y=query(x,L,mid,k);
    ll z=query(x+1,mid+1,R,k);
    return y+z;
}

int main()
{
    int i,j,u,v,c,n,m;
    ll ans ;
    scanf("%d %d",&n,&m);
    for(i=1; i<=n; i++)
        scanf("%d",&num[i]);
    for(i=1; i<n; i++)
    {
        scanf("%d %d",&u,&v);
        edges[u].push_back(v);
        edges[v].push_back(u);
    }
    dfs(1,1);
    for(i=0; i<m; i++)
    {
        scanf("%d",&j);
        if(j==1)
        {
            scanf("%d %d",&u,&v);
            update(1,1,n,Time[u].first,Time[u].second,v*coeff[u]);
        }
        else
        {
            scanf("%d",&u);
            ans = query(1,1,n,Time[u].second);
            ans = (ans*coeff[u])+num[u];
            printf("%lld\n",ans);
        }
    }
}


#include <bits/stdc++.h>
// created [2020/03/21] 16:00:34
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"

using i32   = int32_t;
using i64   = int64_t;
using u32   = uint32_t;
using u64   = uint64_t;
using uint  = unsigned int;
using usize = std::size_t;
using ll    = long long;
using ull   = unsigned long long;
using ld    = long double;
template<typename T, usize n>
using arr = T (&)[n];
template<typename T, usize n>
using c_arr = const T (&)[n];
template<typename T>
using max_heap = std::priority_queue<T>;
template<typename T>
using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template<typename T> constexpr T popcount(const T u) { return u ? static_cast<T>(__builtin_popcountll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T log2p1(const T u) { return u ? static_cast<T>(64 - __builtin_clzll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T msbp1(const T u) { return log2p1(u); }
template<typename T> constexpr T lsbp1(const T u) { return __builtin_ffsll(u); }
template<typename T> constexpr T clog(const T u) { return u ? log2p1(u - 1) : static_cast<T>(u); }
template<typename T> constexpr bool ispow2(const T u) { return u and (static_cast<u64>(u) & static_cast<u64>(u - 1)) == 0; }
template<typename T> constexpr T ceil2(const T u) { return static_cast<T>(1) << clog(u); }
template<typename T> constexpr T floor2(const T u) { return u == 0 ? static_cast<T>(0) : static_cast<T>(1) << (log2p1(u) - 1); }
template<typename T> constexpr bool btest(const T mask, const usize ind) { return static_cast<bool>((static_cast<u64>(mask) >> ind) & static_cast<u64>(1)); }
template<typename T> void bset(T& mask, const usize ind) { mask |= (static_cast<T>(1) << ind); }
template<typename T> void breset(T& mask, const usize ind) { mask &= ~(static_cast<T>(1) << ind); }
template<typename T> void bflip(T& mask, const usize ind) { mask ^= (static_cast<T>(1) << ind); }
template<typename T> void bset(T& mask, const usize ind, const bool b) { (b ? bset(mask, ind) : breset(mask, ind)); }
template<typename T> constexpr T bcut(const T mask, const usize ind) { return ind == 0 ? static_cast<T>(0) : static_cast<T>((static_cast<u64>(mask) << (64 - ind)) >> (64 - ind)); }
template<typename T> bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template<typename T> bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
constexpr unsigned int mod                  = 1000000007;
template<typename T> constexpr T inf_v      = std::numeric_limits<T>::max() / 4;
template<typename Real> constexpr Real pi_v = Real{3.141592653589793238462643383279502884};
auto mfp = [](auto&& f) { return [=](auto&&... args) { return f(f, std::forward<decltype(args)>(args)...); }; };

template<typename T>
T in()
{
    T v;
    return std::cin >> v, v;
}
template<typename T, typename Uint, usize n, usize i>
T in_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type) { return in<T>(); }
template<typename T, typename Uint, usize n, usize i>
auto in_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type& szs)
{
    const usize s = (usize)szs[i];
    std::vector<decltype(in_v<T, Uint, n, i + 1>(szs))> ans(s);
    for (usize j = 0; j < s; j++) { ans[j] = in_v<T, Uint, n, i + 1>(szs); }
    return ans;
}
template<typename T, typename Uint, usize n>
auto in_v(c_arr<Uint, n> szs) { return in_v<T, Uint, n, 0>(szs); }
template<typename... Types>
auto in_t() { return std::tuple<std::decay_t<Types>...>{in<Types>()...}; }
struct io_init
{
    io_init()
    {
        std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(20);
    }
    void clear()
    {
        std::cin.tie(), std::ios::sync_with_stdio(true);
    }
} io_setting;

int out() { return 0; }
template<typename T>
int out(const T& v) { return std::cout << v, 0; }
template<typename T>
int out(const std::vector<T>& v)
{
    for (usize i = 0; i < v.size(); i++) {
        if (i > 0) { std::cout << ' '; }
        out(v[i]);
    }
    return 0;
}
template<typename T1, typename T2>
int out(const std::pair<T1, T2>& v) { return out(v.first), std::cout << ' ', out(v.second), 0; }
template<typename T, typename... Args>
int out(const T& v, const Args... args) { return out(v), std::cout << ' ', out(args...), 0; }
template<typename... Args>
int outln(const Args... args) { return out(args...), std::cout << '\n', 0; }
template<typename... Args>
int outel(const Args... args) { return out(args...), std::cout << std::endl, 0; }
#    define SHOW(...) static_cast<void>(0)
constexpr ull TEN(const usize n) { return n == 0 ? 1ULL : TEN(n - 1) * 10ULL; }

template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type, const T& v = T{}) { return v; }
template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type szs, const T& v = T{})
{
    const usize s = (usize)szs[i];
    return std::vector<decltype(make_v<T, Uint, n, i + 1>(szs, v))>(s, make_v<T, Uint, n, i + 1>(szs, v));
}
template<typename T, typename Uint, usize n>
auto make_v(c_arr<Uint, n> szs, const T& t = T{}) { return make_v<T, Uint, n, 0>(szs, t); }

template<typename Cost = usize>
struct edge
{
    using cost_type = Cost;
    usize u, v;
    Cost c;
    edge(const usize u, const usize v) : u{u}, v{v}, c{1} {}
    edge(const usize u, const usize v, const Cost& c) : u{u}, v{v}, c{c} {}
    operator usize() const { return v; }
    usize from() const { return u; }
    usize to() const { return v; }
    Cost cost() const { return c; }
    friend std::ostream& operator<<(std::ostream& os, const edge& e) { return os << e.u << "->" << e.v << ":" << e.c; }
};
template<typename Edge>
class base_graph
{
public:
    base_graph(const usize n) : v{n}, es(n), res(n) {}
    void add_edge(const usize u, const usize v, const bool bi = false)
    {
        es[u].emplace_back(u, v), res[v].emplace_back(v, u);
        if (bi) { es[v].emplace_back(v, u), res[u].emplace_back(u, v); }
    }
    template<typename Cost>
    void add_edge(const usize u, const usize v, const Cost& c, const bool bi = false)
    {
        es[u].emplace_back(u, v, c), res[v].emplace_back(v, u, c);
        if (bi) { es[v].emplace_back(v, u, c), res[u].emplace_back(u, v, c); }
    }
    std::vector<Edge>& operator[](const usize u) { return es[u]; }
    const std::vector<Edge>& operator[](const usize u) const { return es[u]; }
    std::vector<Edge>& from(const usize u) { return es[u]; }
    const std::vector<Edge>& from(const usize u) const { return es[u]; }
    std::vector<Edge>& to(const usize v) { return res[v]; }
    const std::vector<Edge>& to(const usize v) const { return res[v]; }
    usize size() const { return v; }
    friend std::ostream& operator<<(std::ostream& os, const base_graph& g)
    {
        for (usize i = 0; i < g.v; i++) {
            for (const auto& e : g.es[i]) { os << e << '\n'; }
        }
        return os;
    }

private:
    usize v;
    std::vector<std::vector<Edge>> es, res;
};
template<typename Edge>
using base_tree = base_graph<Edge>;
using graph     = base_graph<edge<>>;
using tree      = base_graph<edge<>>;
template<typename Cost>
using cost_graph = base_graph<edge<Cost>>;
template<typename Cost>
using cost_tree = base_graph<edge<Cost>>;
template<typename Edge = edge<>>
class hl_decomp
{
public:
    hl_decomp(base_tree<Edge>& tree, const usize r = 0) : par(tree.size(), tree.size()), top{par}, in{par}, rin{par}, out{par}
    {
        const usize n = tree.size();
        std::vector<usize> sz(n, 1);
        auto dfs1 = [&](auto&& self, const usize s, const usize p) -> usize {
            par[s] = p;
            for (auto& e : tree[s]) {
                const usize to = e.to();
                if (p == to) { continue; }
                sz[s] += self(self, to, s);
                if (sz[to] > sz[tree[s][0].to()]) { std::swap(e, tree[s].front()); }
            }
            return sz[s];
        };
        dfs1(dfs1, r, n);
        top[r]    = r;
        auto dfs2 = [&](auto&& self, const usize s, const usize p, usize& ind) -> void {
            in[s] = ind++, rin[in[s]] = s;
            for (const auto& e : tree[s]) {
                const usize to = e.to();
                if (to == p) { continue; }
                top[to] = (to == tree[s][0].to() ? top[s] : to);
                self(self, to, s, ind);
            }
            out[s] = ind;
        };
        usize ind = 0;
        dfs2(dfs2, r, n, ind);
    }
    usize pos(const usize v) const { return in[v]; }
    usize at(const usize n) const { return rin[n]; }
    std::pair<usize, usize> sub(const usize v) const { return {in[v], out[v]}; }
    std::vector<std::pair<usize, usize>> path(usize u, usize v, const bool edgeWeight = false) const
    {
        using P = std::pair<usize, usize>;
        std::vector<P> head, tail;
        for (usize pu = top[u], pv = top[v]; pu != pv;) {
            if (in[pu] < in[pv]) {
                tail.push_back({in[pv], in[v]});
                v = par[pv], pv = top[v];
            } else {
                tail.push_back({in[u], in[pu]});
                u = par[pu], pu = top[u];
            }
        }
        if (edgeWeight) {
            if (std::abs((int)in[u] - (int)in[v]) >= 1) { head.push_back(in[u] < in[v] ? P{in[u] + 1, in[v]} : P{in[u], in[v] + 1}); }
        } else {
            head.push_back({in[u], in[v]});
        }
        std::reverse(tail.begin(), tail.end());
        for (const auto& p : tail) { head.push_back(p); }
        return head;
    }
    friend std::ostream& operator<<(std::ostream& os, const hl_decomp& hld)
    {
        os << "{";
        for (const usize v : hld.rin()) { os << v << ","; }
        return os << "}";
    }

private:
    std::vector<usize> par, top, in, rin, out;
};

template<typename ValueMonoid>
class segtree
{
public:
    using value_monoid_type = ValueMonoid;
    using value_type        = typename value_monoid_type::value_type;
    segtree(const usize sz, const value_type initial = value_monoid_type::id()) : sz{sz}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        if (initial != value_monoid_type::id()) {
            std::fill(val.begin() + half, val.end(), initial);
            for (usize i = half - 1; i >= 1; i--) { up(i); }
        }
    }
    template<typename InIt>
    segtree(const InIt first, const InIt last) : sz{static_cast<usize>(std::distance(first, last))}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        std::copy(first, last, val.begin() + half);
        for (usize i = half - 1; i >= 1; i--) { up(i); }
    }
    value_type get(const usize a) const { return assert(a < sz), val[a + half]; }
    void set(usize a, const value_type& v)
    {
        assert(a < sz);
        val[a += half] = v;
        while (a >>= 1) { up(a); }
    }
    value_type fold(usize l, usize r) const
    {
        assert(l < r), assert(r <= sz);
        value_type accl = value_monoid_type::id(), accr = value_monoid_type::id();
        for (l += half, r += half; l < r; l >>= 1, r >>= 1) {
            if (l & 1) { accl = value_monoid_type::merge(accl, val[l++]); }
            if (r & 1) { accr = value_monoid_type::merge(val[--r], accr); }
        }
        return value_monoid_type::merge(accl, accr);
    }
    usize size() const { return sz; }
    friend std::ostream& operator<<(std::ostream& os, const segtree& seg)
    {
        os << "[";
        for (usize i = seg.half; i < seg.half + seg.sz; i++) { os << seg.val[i] << (i + 1 == seg.half + seg.sz ? "" : ","); }
        return (os << "]\n");
    }

private:
    void up(const usize i) { val[i] = value_monoid_type::merge(val[i << 1], val[i << 1 | 1]); }
    const usize sz, half;
    std::vector<value_type> val;
};
template<typename Element>
struct sum
{
    using element_type = Element;
    using value_type   = element_type;
    sum()              = delete;
    static value_type merge(const value_type& a, const value_type& b) { return a + b; }
    static constexpr value_type id() { return value_type{}; }
};
int main()
{
    const auto [N, Q] = in_t<int, int>();
    const auto as     = in_v<ll>({N});
    graph g(N);
    for (int i = 0; i < N - 1; i++) {
        const auto u = in<int>() - 1, v = in<int>() - 1;
        g.add_edge(u, v, true);
    }
    std::vector<ll> coeff(N, 1);
    mfp([&](auto&& self, const int s, const int p) -> void {
        for (const int to : g[s]) {
            if (to == p) { continue; }
            self(self, to, s);
            coeff[to] = -coeff[s];
        }
    })(0, -1);
    hl_decomp hld(g);
    segtree<sum<ll>> seg(N, 0LL);
    for (int i = 0; i < Q; i++) {
        const auto t = in<int>();
        if (t == 1) {
            const auto x  = in<int>() - 1;
            const auto v  = in<ll>();
            const int pos = hld.pos(x);
            seg.set(pos, seg.get(pos) + coeff[x] * v);
        } else {
            const auto x  = in<int>() - 1;
            const auto ps = hld.path(x, 0);
            ll sum        = 0;
            for (const auto& p : ps) {
                int l = p.first, r = p.second;
                if (l > r) { std::swap(l, r); }
                r++;
                sum += seg.fold(l, r);
            }
            outln(sum * coeff[x] + as[x]);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
// created [2020/03/21] 16:00:34
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"

using i32   = int32_t;
using i64   = int64_t;
using u32   = uint32_t;
using u64   = uint64_t;
using uint  = unsigned int;
using usize = std::size_t;
using ll    = long long;
using ull   = unsigned long long;
using ld    = long double;
template<typename T, usize n>
using arr = T (&)[n];
template<typename T, usize n>
using c_arr = const T (&)[n];
template<typename T>
using max_heap = std::priority_queue<T>;
template<typename T>
using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template<typename T> constexpr T popcount(const T u) { return u ? static_cast<T>(__builtin_popcountll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T log2p1(const T u) { return u ? static_cast<T>(64 - __builtin_clzll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T msbp1(const T u) { return log2p1(u); }
template<typename T> constexpr T lsbp1(const T u) { return __builtin_ffsll(u); }
template<typename T> constexpr T clog(const T u) { return u ? log2p1(u - 1) : static_cast<T>(u); }
template<typename T> constexpr bool ispow2(const T u) { return u and (static_cast<u64>(u) & static_cast<u64>(u - 1)) == 0; }
template<typename T> constexpr T ceil2(const T u) { return static_cast<T>(1) << clog(u); }
template<typename T> constexpr T floor2(const T u) { return u == 0 ? static_cast<T>(0) : static_cast<T>(1) << (log2p1(u) - 1); }
template<typename T> constexpr bool btest(const T mask, const usize ind) { return static_cast<bool>((static_cast<u64>(mask) >> ind) & static_cast<u64>(1)); }
template<typename T> void bset(T& mask, const usize ind) { mask |= (static_cast<T>(1) << ind); }
template<typename T> void breset(T& mask, const usize ind) { mask &= ~(static_cast<T>(1) << ind); }
template<typename T> void bflip(T& mask, const usize ind) { mask ^= (static_cast<T>(1) << ind); }
template<typename T> void bset(T& mask, const usize ind, const bool b) { (b ? bset(mask, ind) : breset(mask, ind)); }
template<typename T> constexpr T bcut(const T mask, const usize ind) { return ind == 0 ? static_cast<T>(0) : static_cast<T>((static_cast<u64>(mask) << (64 - ind)) >> (64 - ind)); }
template<typename T> bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template<typename T> bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
constexpr unsigned int mod                  = 1000000007;
template<typename T> constexpr T inf_v      = std::numeric_limits<T>::max() / 4;
template<typename Real> constexpr Real pi_v = Real{3.141592653589793238462643383279502884};
auto mfp = [](auto&& f) { return [=](auto&&... args) { return f(f, std::forward<decltype(args)>(args)...); }; };

template<typename T>
T in()
{
    T v;
    return std::cin >> v, v;
}
template<typename T, typename Uint, usize n, usize i>
T in_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type) { return in<T>(); }
template<typename T, typename Uint, usize n, usize i>
auto in_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type& szs)
{
    const usize s = (usize)szs[i];
    std::vector<decltype(in_v<T, Uint, n, i + 1>(szs))> ans(s);
    for (usize j = 0; j < s; j++) { ans[j] = in_v<T, Uint, n, i + 1>(szs); }
    return ans;
}
template<typename T, typename Uint, usize n>
auto in_v(c_arr<Uint, n> szs) { return in_v<T, Uint, n, 0>(szs); }
template<typename... Types>
auto in_t() { return std::tuple<std::decay_t<Types>...>{in<Types>()...}; }
struct io_init
{
    io_init()
    {
        std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(20);
    }
    void clear()
    {
        std::cin.tie(), std::ios::sync_with_stdio(true);
    }
} io_setting;

int out() { return 0; }
template<typename T>
int out(const T& v) { return std::cout << v, 0; }
template<typename T>
int out(const std::vector<T>& v)
{
    for (usize i = 0; i < v.size(); i++) {
        if (i > 0) { std::cout << ' '; }
        out(v[i]);
    }
    return 0;
}
template<typename T1, typename T2>
int out(const std::pair<T1, T2>& v) { return out(v.first), std::cout << ' ', out(v.second), 0; }
template<typename T, typename... Args>
int out(const T& v, const Args... args) { return out(v), std::cout << ' ', out(args...), 0; }
template<typename... Args>
int outln(const Args... args) { return out(args...), std::cout << '\n', 0; }
template<typename... Args>
int outel(const Args... args) { return out(args...), std::cout << std::endl, 0; }
#    define SHOW(...) static_cast<void>(0)
constexpr ull TEN(const usize n) { return n == 0 ? 1ULL : TEN(n - 1) * 10ULL; }

template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type, const T& v = T{}) { return v; }
template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type szs, const T& v = T{})
{
    const usize s = (usize)szs[i];
    return std::vector<decltype(make_v<T, Uint, n, i + 1>(szs, v))>(s, make_v<T, Uint, n, i + 1>(szs, v));
}
template<typename T, typename Uint, usize n>
auto make_v(c_arr<Uint, n> szs, const T& t = T{}) { return make_v<T, Uint, n, 0>(szs, t); }

template<typename Cost = usize>
struct edge
{
    using cost_type = Cost;
    usize u, v;
    Cost c;
    edge(const usize u, const usize v) : u{u}, v{v}, c{1} {}
    edge(const usize u, const usize v, const Cost& c) : u{u}, v{v}, c{c} {}
    operator usize() const { return v; }
    usize from() const { return u; }
    usize to() const { return v; }
    Cost cost() const { return c; }
    friend std::ostream& operator<<(std::ostream& os, const edge& e) { return os << e.u << "->" << e.v << ":" << e.c; }
};
template<typename Edge>
class base_graph
{
public:
    base_graph(const usize n) : v{n}, es(n), res(n) {}
    void add_edge(const usize u, const usize v, const bool bi = false)
    {
        es[u].emplace_back(u, v), res[v].emplace_back(v, u);
        if (bi) { es[v].emplace_back(v, u), res[u].emplace_back(u, v); }
    }
    template<typename Cost>
    void add_edge(const usize u, const usize v, const Cost& c, const bool bi = false)
    {
        es[u].emplace_back(u, v, c), res[v].emplace_back(v, u, c);
        if (bi) { es[v].emplace_back(v, u, c), res[u].emplace_back(u, v, c); }
    }
    std::vector<Edge>& operator[](const usize u) { return es[u]; }
    const std::vector<Edge>& operator[](const usize u) const { return es[u]; }
    std::vector<Edge>& from(const usize u) { return es[u]; }
    const std::vector<Edge>& from(const usize u) const { return es[u]; }
    std::vector<Edge>& to(const usize v) { return res[v]; }
    const std::vector<Edge>& to(const usize v) const { return res[v]; }
    usize size() const { return v; }
    friend std::ostream& operator<<(std::ostream& os, const base_graph& g)
    {
        for (usize i = 0; i < g.v; i++) {
            for (const auto& e : g.es[i]) { os << e << '\n'; }
        }
        return os;
    }

private:
    usize v;
    std::vector<std::vector<Edge>> es, res;
};
template<typename Edge>
using base_tree = base_graph<Edge>;
using graph     = base_graph<edge<>>;
using tree      = base_graph<edge<>>;
template<typename Cost>
using cost_graph = base_graph<edge<Cost>>;
template<typename Cost>
using cost_tree = base_graph<edge<Cost>>;
template<typename Edge = edge<>>
class hl_decomp
{
public:
    hl_decomp(base_tree<Edge>& tree, const usize r = 0) : par(tree.size(), tree.size()), top{par}, in{par}, rin{par}, out{par}
    {
        const usize n = tree.size();
        std::vector<usize> sz(n, 1);
        auto dfs1 = [&](auto&& self, const usize s, const usize p) -> usize {
            par[s] = p;
            for (auto& e : tree[s]) {
                const usize to = e.to();
                if (p == to) { continue; }
                sz[s] += self(self, to, s);
                if (sz[to] > sz[tree[s][0].to()]) { std::swap(e, tree[s].front()); }
            }
            return sz[s];
        };
        dfs1(dfs1, r, n);
        top[r]    = r;
        auto dfs2 = [&](auto&& self, const usize s, const usize p, usize& ind) -> void {
            in[s] = ind++, rin[in[s]] = s;
            for (const auto& e : tree[s]) {
                const usize to = e.to();
                if (to == p) { continue; }
                top[to] = (to == tree[s][0].to() ? top[s] : to);
                self(self, to, s, ind);
            }
            out[s] = ind;
        };
        usize ind = 0;
        dfs2(dfs2, r, n, ind);
    }
    usize pos(const usize v) const { return in[v]; }
    usize at(const usize n) const { return rin[n]; }
    std::pair<usize, usize> sub(const usize v) const { return {in[v], out[v]}; }
    std::vector<std::pair<usize, usize>> path(usize u, usize v, const bool edgeWeight = false) const
    {
        using P = std::pair<usize, usize>;
        std::vector<P> head, tail;
        for (usize pu = top[u], pv = top[v]; pu != pv;) {
            if (in[pu] < in[pv]) {
                tail.push_back({in[pv], in[v]});
                v = par[pv], pv = top[v];
            } else {
                tail.push_back({in[u], in[pu]});
                u = par[pu], pu = top[u];
            }
        }
        if (edgeWeight) {
            if (std::abs((int)in[u] - (int)in[v]) >= 1) { head.push_back(in[u] < in[v] ? P{in[u] + 1, in[v]} : P{in[u], in[v] + 1}); }
        } else {
            head.push_back({in[u], in[v]});
        }
        std::reverse(tail.begin(), tail.end());
        for (const auto& p : tail) { head.push_back(p); }
        return head;
    }
    friend std::ostream& operator<<(std::ostream& os, const hl_decomp& hld)
    {
        os << "{";
        for (const usize v : hld.rin()) { os << v << ","; }
        return os << "}";
    }

private:
    std::vector<usize> par, top, in, rin, out;
};

template<typename ValueMonoid>
class segtree
{
public:
    using value_monoid_type = ValueMonoid;
    using value_type        = typename value_monoid_type::value_type;
    segtree(const usize sz, const value_type initial = value_monoid_type::id()) : sz{sz}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        if (initial != value_monoid_type::id()) {
            std::fill(val.begin() + half, val.end(), initial);
            for (usize i = half - 1; i >= 1; i--) { up(i); }
        }
    }
    template<typename InIt>
    segtree(const InIt first, const InIt last) : sz{static_cast<usize>(std::distance(first, last))}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        std::copy(first, last, val.begin() + half);
        for (usize i = half - 1; i >= 1; i--) { up(i); }
    }
    value_type get(const usize a) const { return assert(a < sz), val[a + half]; }
    void set(usize a, const value_type& v)
    {
        assert(a < sz);
        val[a += half] = v;
        while (a >>= 1) { up(a); }
    }
    value_type fold(usize l, usize r) const
    {
        assert(l < r), assert(r <= sz);
        value_type accl = value_monoid_type::id(), accr = value_monoid_type::id();
        for (l += half, r += half; l < r; l >>= 1, r >>= 1) {
            if (l & 1) { accl = value_monoid_type::merge(accl, val[l++]); }
            if (r & 1) { accr = value_monoid_type::merge(val[--r], accr); }
        }
        return value_monoid_type::merge(accl, accr);
    }
    usize size() const { return sz; }
    friend std::ostream& operator<<(std::ostream& os, const segtree& seg)
    {
        os << "[";
        for (usize i = seg.half; i < seg.half + seg.sz; i++) { os << seg.val[i] << (i + 1 == seg.half + seg.sz ? "" : ","); }
        return (os << "]\n");
    }

private:
    void up(const usize i) { val[i] = value_monoid_type::merge(val[i << 1], val[i << 1 | 1]); }
    const usize sz, half;
    std::vector<value_type> val;
};
template<typename Element>
struct sum
{
    using element_type = Element;
    using value_type   = element_type;
    sum()              = delete;
    static value_type merge(const value_type& a, const value_type& b) { return a + b; }
    static constexpr value_type id() { return value_type{}; }
};
int main()
{
    const auto [N, Q] = in_t<int, int>();
    const auto as     = in_v<ll>({N});
    graph g(N);
    for (int i = 0; i < N - 1; i++) {
        const auto u = in<int>() - 1, v = in<int>() - 1;
        g.add_edge(u, v, true);
    }
    std::vector<ll> coeff(N, 1);
    mfp([&](auto&& self, const int s, const int p) -> void {
        for (const int to : g[s]) {
            if (to == p) { continue; }
            self(self, to, s);
            coeff[to] = -coeff[s];
        }
    });
    hl_decomp hld(g);
    segtree<sum<ll>> seg(N, 0LL);
    for (int i = 0; i < Q; i++) {
        const auto t = in<int>();
        if (t == 1) {
            const auto x  = in<int>() - 1;
            const auto v  = in<ll>();
            const int pos = hld.pos(x);
            seg.set(pos, seg.get(pos) + coeff[x] * v);
        } else {
            const auto x  = in<int>() - 1;
            const auto ps = hld.path(x, 0);
            ll sum        = 0;
            for (const auto& p : ps) {
                int l = p.first, r = p.second;
                if (l > r) { std::swap(l, r); }
                r++;
                sum += seg.fold(l, r) * sum;
            }
            outln(sum * coeff[x] + as[x]);
        }
    }
    return 0;
}


#include <bits/stdc++.h>
// created [2020/03/21] 16:00:34
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"

using i32   = int32_t;
using i64   = int64_t;
using u32   = uint32_t;
using u64   = uint64_t;
using uint  = unsigned int;
using usize = std::size_t;
using ll    = long long;
using ull   = unsigned long long;
using ld    = long double;
template<typename T, usize n>
using arr = T (&)[n];
template<typename T, usize n>
using c_arr = const T (&)[n];
template<typename T>
using max_heap = std::priority_queue<T>;
template<typename T>
using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template<typename T> constexpr T popcount(const T u) { return u ? static_cast<T>(__builtin_popcountll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T log2p1(const T u) { return u ? static_cast<T>(64 - __builtin_clzll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T msbp1(const T u) { return log2p1(u); }
template<typename T> constexpr T lsbp1(const T u) { return __builtin_ffsll(u); }
template<typename T> constexpr T clog(const T u) { return u ? log2p1(u - 1) : static_cast<T>(u); }
template<typename T> constexpr bool ispow2(const T u) { return u and (static_cast<u64>(u) & static_cast<u64>(u - 1)) == 0; }
template<typename T> constexpr T ceil2(const T u) { return static_cast<T>(1) << clog(u); }
template<typename T> constexpr T floor2(const T u) { return u == 0 ? static_cast<T>(0) : static_cast<T>(1) << (log2p1(u) - 1); }
template<typename T> constexpr bool btest(const T mask, const usize ind) { return static_cast<bool>((static_cast<u64>(mask) >> ind) & static_cast<u64>(1)); }
template<typename T> void bset(T& mask, const usize ind) { mask |= (static_cast<T>(1) << ind); }
template<typename T> void breset(T& mask, const usize ind) { mask &= ~(static_cast<T>(1) << ind); }
template<typename T> void bflip(T& mask, const usize ind) { mask ^= (static_cast<T>(1) << ind); }
template<typename T> void bset(T& mask, const usize ind, const bool b) { (b ? bset(mask, ind) : breset(mask, ind)); }
template<typename T> constexpr T bcut(const T mask, const usize ind) { return ind == 0 ? static_cast<T>(0) : static_cast<T>((static_cast<u64>(mask) << (64 - ind)) >> (64 - ind)); }
template<typename T> bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template<typename T> bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
constexpr unsigned int mod                  = 1000000007;
template<typename T> constexpr T inf_v      = std::numeric_limits<T>::max() / 4;
template<typename Real> constexpr Real pi_v = Real{3.141592653589793238462643383279502884};
auto mfp = [](auto&& f) { return [=](auto&&... args) { return f(f, std::forward<decltype(args)>(args)...); }; };

template<typename T>
T in()
{
    T v;
    return std::cin >> v, v;
}
template<typename T, typename Uint, usize n, usize i>
T in_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type) { return in<T>(); }
template<typename T, typename Uint, usize n, usize i>
auto in_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type& szs)
{
    const usize s = (usize)szs[i];
    std::vector<decltype(in_v<T, Uint, n, i + 1>(szs))> ans(s);
    for (usize j = 0; j < s; j++) { ans[j] = in_v<T, Uint, n, i + 1>(szs); }
    return ans;
}
template<typename T, typename Uint, usize n>
auto in_v(c_arr<Uint, n> szs) { return in_v<T, Uint, n, 0>(szs); }
template<typename... Types>
auto in_t() { return std::tuple<std::decay_t<Types>...>{in<Types>()...}; }
struct io_init
{
    io_init()
    {
        std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(20);
    }
    void clear()
    {
        std::cin.tie(), std::ios::sync_with_stdio(true);
    }
} io_setting;

int out() { return 0; }
template<typename T>
int out(const T& v) { return std::cout << v, 0; }
template<typename T>
int out(const std::vector<T>& v)
{
    for (usize i = 0; i < v.size(); i++) {
        if (i > 0) { std::cout << ' '; }
        out(v[i]);
    }
    return 0;
}
template<typename T1, typename T2>
int out(const std::pair<T1, T2>& v) { return out(v.first), std::cout << ' ', out(v.second), 0; }
template<typename T, typename... Args>
int out(const T& v, const Args... args) { return out(v), std::cout << ' ', out(args...), 0; }
template<typename... Args>
int outln(const Args... args) { return out(args...), std::cout << '\n', 0; }
template<typename... Args>
int outel(const Args... args) { return out(args...), std::cout << std::endl, 0; }
#    define SHOW(...) static_cast<void>(0)
constexpr ull TEN(const usize n) { return n == 0 ? 1ULL : TEN(n - 1) * 10ULL; }

template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type, const T& v = T{}) { return v; }
template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type szs, const T& v = T{})
{
    const usize s = (usize)szs[i];
    return std::vector<decltype(make_v<T, Uint, n, i + 1>(szs, v))>(s, make_v<T, Uint, n, i + 1>(szs, v));
}
template<typename T, typename Uint, usize n>
auto make_v(c_arr<Uint, n> szs, const T& t = T{}) { return make_v<T, Uint, n, 0>(szs, t); }

template<typename Cost = usize>
struct edge
{
    using cost_type = Cost;
    usize u, v;
    Cost c;
    edge(const usize u, const usize v) : u{u}, v{v}, c{1} {}
    edge(const usize u, const usize v, const Cost& c) : u{u}, v{v}, c{c} {}
    operator usize() const { return v; }
    usize from() const { return u; }
    usize to() const { return v; }
    Cost cost() const { return c; }
    friend std::ostream& operator<<(std::ostream& os, const edge& e) { return os << e.u << "->" << e.v << ":" << e.c; }
};
template<typename Edge>
class base_graph
{
public:
    base_graph(const usize n) : v{n}, es(n), res(n) {}
    void add_edge(const usize u, const usize v, const bool bi = false)
    {
        es[u].emplace_back(u, v), res[v].emplace_back(v, u);
        if (bi) { es[v].emplace_back(v, u), res[u].emplace_back(u, v); }
    }
    template<typename Cost>
    void add_edge(const usize u, const usize v, const Cost& c, const bool bi = false)
    {
        es[u].emplace_back(u, v, c), res[v].emplace_back(v, u, c);
        if (bi) { es[v].emplace_back(v, u, c), res[u].emplace_back(u, v, c); }
    }
    std::vector<Edge>& operator[](const usize u) { return es[u]; }
    const std::vector<Edge>& operator[](const usize u) const { return es[u]; }
    std::vector<Edge>& from(const usize u) { return es[u]; }
    const std::vector<Edge>& from(const usize u) const { return es[u]; }
    std::vector<Edge>& to(const usize v) { return res[v]; }
    const std::vector<Edge>& to(const usize v) const { return res[v]; }
    usize size() const { return v; }
    friend std::ostream& operator<<(std::ostream& os, const base_graph& g)
    {
        for (usize i = 0; i < g.v; i++) {
            for (const auto& e : g.es[i]) { os << e << '\n'; }
        }
        return os;
    }

private:
    usize v;
    std::vector<std::vector<Edge>> es, res;
};
template<typename Edge>
using base_tree = base_graph<Edge>;
using graph     = base_graph<edge<>>;
using tree      = base_graph<edge<>>;
template<typename Cost>
using cost_graph = base_graph<edge<Cost>>;
template<typename Cost>
using cost_tree = base_graph<edge<Cost>>;
template<typename Edge = edge<>>
class hl_decomp
{
public:
    hl_decomp(base_tree<Edge>& tree, const usize r = 0) : par(tree.size(), tree.size()), top{par}, in{par}, rin{par}, out{par}
    {
        const usize n = tree.size();
        std::vector<usize> sz(n, 1);
        auto dfs1 = [&](auto&& self, const usize s, const usize p) -> usize {
            par[s] = p;
            for (auto& e : tree[s]) {
                const usize to = e.to();
                if (p == to) { continue; }
                sz[s] += self(self, to, s);
                if (sz[to] > sz[tree[s][0].to()]) { std::swap(e, tree[s].front()); }
            }
            return sz[s];
        };
        dfs1(dfs1, r, n);
        top[r]    = r;
        auto dfs2 = [&](auto&& self, const usize s, const usize p, usize& ind) -> void {
            in[s] = ind++, rin[in[s]] = s;
            for (const auto& e : tree[s]) {
                const usize to = e.to();
                if (to == p) { continue; }
                top[to] = (to == tree[s][0].to() ? top[s] : to);
                self(self, to, s, ind);
            }
            out[s] = ind;
        };
        usize ind = 0;
        dfs2(dfs2, r, n, ind);
    }
    usize pos(const usize v) const { return in[v]; }
    usize at(const usize n) const { return rin[n]; }
    std::pair<usize, usize> sub(const usize v) const { return {in[v], out[v]}; }
    std::vector<std::pair<usize, usize>> path(usize u, usize v, const bool edgeWeight = false) const
    {
        using P = std::pair<usize, usize>;
        std::vector<P> head, tail;
        for (usize pu = top[u], pv = top[v]; pu != pv;) {
            if (in[pu] < in[pv]) {
                tail.push_back({in[pv], in[v]});
                v = par[pv], pv = top[v];
            } else {
                tail.push_back({in[u], in[pu]});
                u = par[pu], pu = top[u];
            }
        }
        if (edgeWeight) {
            if (std::abs((int)in[u] - (int)in[v]) >= 1) { head.push_back(in[u] < in[v] ? P{in[u] + 1, in[v]} : P{in[u], in[v] + 1}); }
        } else {
            head.push_back({in[u], in[v]});
        }
        std::reverse(tail.begin(), tail.end());
        for (const auto& p : tail) { head.push_back(p); }
        return head;
    }
    friend std::ostream& operator<<(std::ostream& os, const hl_decomp& hld)
    {
        os << "{";
        for (const usize v : hld.rin()) { os << v << ","; }
        return os << "}";
    }

private:
    std::vector<usize> par, top, in, rin, out;
};

template<typename ValueMonoid>
class segtree
{
public:
    using value_monoid_type = ValueMonoid;
    using value_type        = typename value_monoid_type::value_type;
    segtree(const usize sz, const value_type initial = value_monoid_type::id()) : sz{sz}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        if (initial != value_monoid_type::id()) {
            std::fill(val.begin() + half, val.end(), initial);
            for (usize i = half - 1; i >= 1; i--) { up(i); }
        }
    }
    template<typename InIt>
    segtree(const InIt first, const InIt last) : sz{static_cast<usize>(std::distance(first, last))}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        std::copy(first, last, val.begin() + half);
        for (usize i = half - 1; i >= 1; i--) { up(i); }
    }
    value_type get(const usize a) const { return assert(a < sz), val[a + half]; }
    void set(usize a, const value_type& v)
    {
        assert(a < sz);
        val[a += half] = v;
        while (a >>= 1) { up(a); }
    }
    value_type fold(usize l, usize r) const
    {
        assert(l < r), assert(r <= sz);
        value_type accl = value_monoid_type::id(), accr = value_monoid_type::id();
        for (l += half, r += half; l < r; l >>= 1, r >>= 1) {
            if (l & 1) { accl = value_monoid_type::merge(accl, val[l++]); }
            if (r & 1) { accr = value_monoid_type::merge(val[--r], accr); }
        }
        return value_monoid_type::merge(accl, accr);
    }
    usize size() const { return sz; }
    friend std::ostream& operator<<(std::ostream& os, const segtree& seg)
    {
        os << "[";
        for (usize i = seg.half; i < seg.half + seg.sz; i++) { os << seg.val[i] << (i + 1 == seg.half + seg.sz ? "" : ","); }
        return (os << "]\n");
    }

private:
    void up(const usize i) { val[i] = value_monoid_type::merge(val[i << 1], val[i << 1 | 1]); }
    const usize sz, half;
    std::vector<value_type> val;
};
template<typename Element>
struct sum
{
    using element_type = Element;
    using value_type   = element_type;
    sum()              = delete;
    static value_type merge(const value_type& a, const value_type& b) { return a + b; }
    static constexpr value_type id() { return value_type{}; }
};
int main()
{
    const auto [N, Q] = in_t<int, int>();
    const auto as     = in_v<ll>({N});
    graph g(N);
    for (int i = 0; i < N - 1; i++) {
        const auto u = in<int>() - 1, v = in<int>() - 1;
        g.add_edge(u, v, true);
    }
    std::vector<ll> coeff(N, 1);
    mfp([&](auto&& self, const int s, const int p) -> void {
        for (const int to : g[s]) {
            if (to == p) { continue; }
            self(self, to, s);
            coeff[to] = -coeff[s];
        }
    });
    hl_decomp hld(g);
    segtree<sum<ll>> seg(N, 0LL);
    for (int i = 0; i < Q; i++) {
        const auto t = in<int>();
        if (t == 1) {
            const auto x  = in<int>() - 1;
            const auto v  = in<ll>();
            const int pos = hld.pos(x);
            seg.set(pos, seg.get(pos) + coeff[x] * v);
        } else {
            const auto x  = in<int>() - 1;
            const auto ps = hld.path(x, 0);
            for (const auto& p : ps) {
                int l = p.first, r = p.second;
                if (l > r) { std::swap(l, r); }
                r++;
                const ll sum = seg.fold(l, r);
                outln(as[x] + coeff[x] * sum);
            }
        }
    }
    return 0;
}


#include <bits/stdc++.h>
// created [2020/03/21] 16:00:34
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wsign-conversion"

using i32   = int32_t;
using i64   = int64_t;
using u32   = uint32_t;
using u64   = uint64_t;
using uint  = unsigned int;
using usize = std::size_t;
using ll    = long long;
using ull   = unsigned long long;
using ld    = long double;
template<typename T, usize n>
using arr = T (&)[n];
template<typename T, usize n>
using c_arr = const T (&)[n];
template<typename T>
using max_heap = std::priority_queue<T>;
template<typename T>
using min_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template<typename T> constexpr T popcount(const T u) { return u ? static_cast<T>(__builtin_popcountll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T log2p1(const T u) { return u ? static_cast<T>(64 - __builtin_clzll(static_cast<u64>(u))) : static_cast<T>(0); }
template<typename T> constexpr T msbp1(const T u) { return log2p1(u); }
template<typename T> constexpr T lsbp1(const T u) { return __builtin_ffsll(u); }
template<typename T> constexpr T clog(const T u) { return u ? log2p1(u - 1) : static_cast<T>(u); }
template<typename T> constexpr bool ispow2(const T u) { return u and (static_cast<u64>(u) & static_cast<u64>(u - 1)) == 0; }
template<typename T> constexpr T ceil2(const T u) { return static_cast<T>(1) << clog(u); }
template<typename T> constexpr T floor2(const T u) { return u == 0 ? static_cast<T>(0) : static_cast<T>(1) << (log2p1(u) - 1); }
template<typename T> constexpr bool btest(const T mask, const usize ind) { return static_cast<bool>((static_cast<u64>(mask) >> ind) & static_cast<u64>(1)); }
template<typename T> void bset(T& mask, const usize ind) { mask |= (static_cast<T>(1) << ind); }
template<typename T> void breset(T& mask, const usize ind) { mask &= ~(static_cast<T>(1) << ind); }
template<typename T> void bflip(T& mask, const usize ind) { mask ^= (static_cast<T>(1) << ind); }
template<typename T> void bset(T& mask, const usize ind, const bool b) { (b ? bset(mask, ind) : breset(mask, ind)); }
template<typename T> constexpr T bcut(const T mask, const usize ind) { return ind == 0 ? static_cast<T>(0) : static_cast<T>((static_cast<u64>(mask) << (64 - ind)) >> (64 - ind)); }
template<typename T> bool chmin(T& a, const T& b) { return (a > b ? a = b, true : false); }
template<typename T> bool chmax(T& a, const T& b) { return (a < b ? a = b, true : false); }
constexpr unsigned int mod                  = 1000000007;
template<typename T> constexpr T inf_v      = std::numeric_limits<T>::max() / 4;
template<typename Real> constexpr Real pi_v = Real{3.141592653589793238462643383279502884};
auto mfp = [](auto&& f) { return [=](auto&&... args) { return f(f, std::forward<decltype(args)>(args)...); }; };

template<typename T>
T in()
{
    T v;
    return std::cin >> v, v;
}
template<typename T, typename Uint, usize n, usize i>
T in_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type) { return in<T>(); }
template<typename T, typename Uint, usize n, usize i>
auto in_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type& szs)
{
    const usize s = (usize)szs[i];
    std::vector<decltype(in_v<T, Uint, n, i + 1>(szs))> ans(s);
    for (usize j = 0; j < s; j++) { ans[j] = in_v<T, Uint, n, i + 1>(szs); }
    return ans;
}
template<typename T, typename Uint, usize n>
auto in_v(c_arr<Uint, n> szs) { return in_v<T, Uint, n, 0>(szs); }
template<typename... Types>
auto in_t() { return std::tuple<std::decay_t<Types>...>{in<Types>()...}; }
struct io_init
{
    io_init()
    {
        std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
        std::cout << std::fixed << std::setprecision(20);
    }
    void clear()
    {
        std::cin.tie(), std::ios::sync_with_stdio(true);
    }
} io_setting;

int out() { return 0; }
template<typename T>
int out(const T& v) { return std::cout << v, 0; }
template<typename T>
int out(const std::vector<T>& v)
{
    for (usize i = 0; i < v.size(); i++) {
        if (i > 0) { std::cout << ' '; }
        out(v[i]);
    }
    return 0;
}
template<typename T1, typename T2>
int out(const std::pair<T1, T2>& v) { return out(v.first), std::cout << ' ', out(v.second), 0; }
template<typename T, typename... Args>
int out(const T& v, const Args... args) { return out(v), std::cout << ' ', out(args...), 0; }
template<typename... Args>
int outln(const Args... args) { return out(args...), std::cout << '\n', 0; }
template<typename... Args>
int outel(const Args... args) { return out(args...), std::cout << std::endl, 0; }
#    define SHOW(...) static_cast<void>(0)
constexpr ull TEN(const usize n) { return n == 0 ? 1ULL : TEN(n - 1) * 10ULL; }

template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i == n), c_arr<Uint, n>>::type, const T& v = T{}) { return v; }
template<typename T, typename Uint, usize n, usize i>
auto make_v(typename std::enable_if<(i < n), c_arr<Uint, n>>::type szs, const T& v = T{})
{
    const usize s = (usize)szs[i];
    return std::vector<decltype(make_v<T, Uint, n, i + 1>(szs, v))>(s, make_v<T, Uint, n, i + 1>(szs, v));
}
template<typename T, typename Uint, usize n>
auto make_v(c_arr<Uint, n> szs, const T& t = T{}) { return make_v<T, Uint, n, 0>(szs, t); }

template<typename Cost = usize>
struct edge
{
    using cost_type = Cost;
    usize u, v;
    Cost c;
    edge(const usize u, const usize v) : u{u}, v{v}, c{1} {}
    edge(const usize u, const usize v, const Cost& c) : u{u}, v{v}, c{c} {}
    operator usize() const { return v; }
    usize from() const { return u; }
    usize to() const { return v; }
    Cost cost() const { return c; }
    friend std::ostream& operator<<(std::ostream& os, const edge& e) { return os << e.u << "->" << e.v << ":" << e.c; }
};
template<typename Edge>
class base_graph
{
public:
    base_graph(const usize n) : v{n}, es(n), res(n) {}
    void add_edge(const usize u, const usize v, const bool bi = false)
    {
        es[u].emplace_back(u, v), res[v].emplace_back(v, u);
        if (bi) { es[v].emplace_back(v, u), res[u].emplace_back(u, v); }
    }
    template<typename Cost>
    void add_edge(const usize u, const usize v, const Cost& c, const bool bi = false)
    {
        es[u].emplace_back(u, v, c), res[v].emplace_back(v, u, c);
        if (bi) { es[v].emplace_back(v, u, c), res[u].emplace_back(u, v, c); }
    }
    std::vector<Edge>& operator[](const usize u) { return es[u]; }
    const std::vector<Edge>& operator[](const usize u) const { return es[u]; }
    std::vector<Edge>& from(const usize u) { return es[u]; }
    const std::vector<Edge>& from(const usize u) const { return es[u]; }
    std::vector<Edge>& to(const usize v) { return res[v]; }
    const std::vector<Edge>& to(const usize v) const { return res[v]; }
    usize size() const { return v; }
    friend std::ostream& operator<<(std::ostream& os, const base_graph& g)
    {
        for (usize i = 0; i < g.v; i++) {
            for (const auto& e : g.es[i]) { os << e << '\n'; }
        }
        return os;
    }

private:
    usize v;
    std::vector<std::vector<Edge>> es, res;
};
template<typename Edge>
using base_tree = base_graph<Edge>;
using graph     = base_graph<edge<>>;
using tree      = base_graph<edge<>>;
template<typename Cost>
using cost_graph = base_graph<edge<Cost>>;
template<typename Cost>
using cost_tree = base_graph<edge<Cost>>;
template<typename Edge = edge<>>
class hl_decomp
{
public:
    hl_decomp(base_tree<Edge>& tree, const usize r = 0) : par(tree.size(), tree.size()), top{par}, in{par}, rin{par}, out{par}
    {
        const usize n = tree.size();
        std::vector<usize> sz(n, 1);
        auto dfs1 = [&](auto&& self, const usize s, const usize p) -> usize {
            par[s] = p;
            for (auto& e : tree[s]) {
                const usize to = e.to();
                if (p == to) { continue; }
                sz[s] += self(self, to, s);
                if (sz[to] > sz[tree[s][0].to()]) { std::swap(e, tree[s].front()); }
            }
            return sz[s];
        };
        dfs1(dfs1, r, n);
        top[r]    = r;
        auto dfs2 = [&](auto&& self, const usize s, const usize p, usize& ind) -> void {
            in[s] = ind++, rin[in[s]] = s;
            for (const auto& e : tree[s]) {
                const usize to = e.to();
                if (to == p) { continue; }
                top[to] = (to == tree[s][0].to() ? top[s] : to);
                self(self, to, s, ind);
            }
            out[s] = ind;
        };
        usize ind = 0;
        dfs2(dfs2, r, n, ind);
    }
    usize pos(const usize v) const { return in[v]; }
    usize at(const usize n) const { return rin[n]; }
    std::pair<usize, usize> sub(const usize v) const { return {in[v], out[v]}; }
    std::vector<std::pair<usize, usize>> path(usize u, usize v, const bool edgeWeight = false) const
    {
        using P = std::pair<usize, usize>;
        std::vector<P> head, tail;
        for (usize pu = top[u], pv = top[v]; pu != pv;) {
            if (in[pu] < in[pv]) {
                tail.push_back({in[pv], in[v]});
                v = par[pv], pv = top[v];
            } else {
                tail.push_back({in[u], in[pu]});
                u = par[pu], pu = top[u];
            }
        }
        if (edgeWeight) {
            if (std::abs((int)in[u] - (int)in[v]) >= 1) { head.push_back(in[u] < in[v] ? P{in[u] + 1, in[v]} : P{in[u], in[v] + 1}); }
        } else {
            head.push_back({in[u], in[v]});
        }
        std::reverse(tail.begin(), tail.end());
        for (const auto& p : tail) { head.push_back(p); }
        return head;
    }
    friend std::ostream& operator<<(std::ostream& os, const hl_decomp& hld)
    {
        os << "{";
        for (const usize v : hld.rin()) { os << v << ","; }
        return os << "}";
    }

private:
    std::vector<usize> par, top, in, rin, out;
};

template<typename ValueMonoid>
class segtree
{
public:
    using value_monoid_type = ValueMonoid;
    using value_type        = typename value_monoid_type::value_type;
    segtree(const usize sz, const value_type initial = value_monoid_type::id()) : sz{sz}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        if (initial != value_monoid_type::id()) {
            std::fill(val.begin() + half, val.end(), initial);
            for (usize i = half - 1; i >= 1; i--) { up(i); }
        }
    }
    template<typename InIt>
    segtree(const InIt first, const InIt last) : sz{static_cast<usize>(std::distance(first, last))}, half{ceil2(sz)}, val(half << 1, value_monoid_type::id())
    {
        std::copy(first, last, val.begin() + half);
        for (usize i = half - 1; i >= 1; i--) { up(i); }
    }
    value_type get(const usize a) const { return assert(a < sz), val[a + half]; }
    void set(usize a, const value_type& v)
    {
        assert(a < sz);
        val[a += half] = v;
        while (a >>= 1) { up(a); }
    }
    value_type fold(usize l, usize r) const
    {
        assert(l < r), assert(r <= sz);
        value_type accl = value_monoid_type::id(), accr = value_monoid_type::id();
        for (l += half, r += half; l < r; l >>= 1, r >>= 1) {
            if (l & 1) { accl = value_monoid_type::merge(accl, val[l++]); }
            if (r & 1) { accr = value_monoid_type::merge(val[--r], accr); }
        }
        return value_monoid_type::merge(accl, accr);
    }
    usize size() const { return sz; }
    friend std::ostream& operator<<(std::ostream& os, const segtree& seg)
    {
        os << "[";
        for (usize i = seg.half; i < seg.half + seg.sz; i++) { os << seg.val[i] << (i + 1 == seg.half + seg.sz ? "" : ","); }
        return (os << "]\n");
    }

private:
    void up(const usize i) { val[i] = value_monoid_type::merge(val[i << 1], val[i << 1 | 1]); }
    const usize sz, half;
    std::vector<value_type> val;
};
template<typename Element>
struct sum
{
    using element_type = Element;
    using value_type   = element_type;
    sum()              = delete;
    static value_type merge(const value_type& a, const value_type& b) { return a + b; }
    static constexpr value_type id() { return value_type{}; }
};
int main()
{
    const auto [N, Q] = in_t<int, int>();
    const auto as     = in_v<ll>({N});
    graph g(N);
    for (int i = 0; i < N - 1; i++) {
        const auto u = in<int>() - 1, v = in<int>() - 1;
        g.add_edge(u, v, true);
    }
    std::vector<ll> coeff(N, 1);
    mfp([&](auto&& self, const int s, const int p) -> void {
        for (const int to : g[s]) {
            if (to == p) { continue; }
            self(self, to, s);
            coeff[to] = -coeff[s];
        }
    });
    hl_decomp hld(g);
    segtree<sum<ll>> seg(N, 0LL);
    for (int i = 0; i < N - 1; i++) {
        const auto t = in<int>();
        if (t == 1) {
            const auto x  = in<int>() - 1;
            const auto v  = in<ll>();
            const int pos = hld.pos(x);
            seg.set(pos, seg.get(pos) + coeff[x] * v);
        } else {
            const auto x  = in<int>() - 1;
            const auto ps = hld.path(x, 0);
            for (const auto& p : ps) {
                int l = p.first, r = p.second;
                if (l > r) { std::swap(l, r); }
                r++;
                const ll sum = seg.fold(l, r);
                outln(coeff[x] * sum);
            }
        }
    }
    return 0;
}