RT
#include<bits/stdc++.h>
using namespace std;
struct edge{int toward,nxt;}line[2000002];
struct node{int x,y,num,lz;}q[2000002];
int n,m,a[2000002],in[2000002],ot[2000002],cntt,cntl,c[2000002],lst[2000002];
int tag[2000002],sumtag[2000002];
void add(int x,int y)
{
line[++cntl].nxt=lst[x];
lst[x]=cntl;
line[cntl].toward=y;
return;
}
void dfsx(int x,int fa)
{
in[x]=++cntt;
c[cntt]=a[x];
tag[cntt]++;
for(int i=lst[x];i;i=line[i].nxt)
{
if(line[i].toward==fa) continue;
dfsx(line[i].toward,x);
}
ot[x]=++cntt;
c[cntt]=-a[x];
tag[cntt]--;
return;
}
void buildtree(int id,int x,int y)
{
q[id].x=x;q[id].y=y;
if(x==y) {q[id].num=c[x];return;}
buildtree(id<<1,x,(x+y)>>1);
buildtree(id<<1|1,(x+y>>1)+1,y);
q[id].num=q[id<<1].num+q[id<<1|1].num;
return;
}
void pudw(int id)
{
if(q[id].x==q[id].y) return;
int ll=id<<1,rr=id<<1|1;
q[ll].num+=q[id].lz*(sumtag[q[ll].y]-sumtag[q[ll].x-1]);
q[ll].lz+=q[id].lz;
q[rr].num+=q[id].lz*(sumtag[q[rr].y]-sumtag[q[rr].x-1]);
q[rr].lz+=q[id].lz;
q[id].lz=0;
return;
}
void mofy(int id,int x,int y,int k)
{
if(q[id].x>y||q[id].y<x) return;
if(q[id].lz) pudw(id);
if(x<=q[id].x&&q[id].y<=y)
{
q[id].lz+=k;
q[id].num+=k*(sumtag[q[id].y]-sumtag[q[id].x-1]);
return;
}
mofy(id<<1,x,y,k);
mofy(id<<1|1,x,y,k);
q[id].num=q[id<<1].num+q[id<<1|1].num;
return;
}
int sum(int id,int x,int y)
{
if(q[id].x>y||q[id].y<x) return 0;
if(q[id].lz) pudw(id);
if(x<=q[id].x&&q[id].y<=y) return q[id].num;
return sum(id<<1,x,y)+sum(id<<1|1,x,y);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfsx(1,0);
n<<=1;
buildtree(1,1,n);
for(int i=1;i<=n;i++) sumtag[i]=sumtag[i-1]+tag[i];
for(int i=1,dd,x,y;i<=m;i++)
{
scanf("%d%d",&dd,&x);
if(dd==1) scanf("%d",&y),mofy(1,in[x],in[x],y),mofy(1,ot[x],ot[x],y);
else if(dd==2) scanf("%d",&y),mofy(1,in[x],ot[x],y);
else printf("%d\n",sum(1,1,in[x]));
}
return 0;
}