#include<cstdio>
#include<cmath>
#include<iostream>
#include<vector>
using namespace std;
int n,m;
vector<int>g[100001];
int a[100001];
int father[100001],dep[100001],wc[100001],sz[100001],dfn[100001],rdfn[100001],top[100001],vistime=0;
long long lzy[400001],w[400001];
void dfs1(int u,int f)
{
dep[u]=dep[f]+1;
father[u]=f;
sz[u]=1;
for(int i=0; i<g[u].size(); i++)
{
int v=g[u][i];
if(v!=f)
{
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[wc[u]])
{
wc[u]=v;
}
}
}
}
void dfs2(int u,int Top)
{
vistime++;
dfn[u]=vistime;
rdfn[vistime]=u;
top[u]=Top;
if(wc[u]!=0)
{
dfs2(wc[u],Top);
for(int i=0; i<g[u].size(); i++)
{
int v=g[u][i];
if(v!=father[u]&&v!=wc[u])
{
dfs2(v,v);
}
}
}
}
void pushup(int u)
{
w[u]=w[u*2]+w[u*2+1];
}
void maketag(int u,int len,long long x)
{
lzy[u]+=x;
w[u]+=len*x;
}
void pushdown(int u,int l,int r)
{
int mid=(l+r)/2;
maketag(u*2,mid-l+1,lzy[u]);
maketag(u*2+1,r-mid,lzy[u]);
lzy[u]=0;
}
bool inrange(int l,int r,int L,int R)
{
return (L<=l)&&(r<=R);
}
bool outrange(int l,int r,int L,int R)
{
return (r<L)||(R<l);
}
void build(int u,int l,int r)
{
if(l==r)
{
w[u]=a[rdfn[l]];
return;
}
int mid=(l+r)/2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
pushup(u);
}
void update_1(int u,int l,int r,int pos,int x)
{
if(l==r)
{
w[u]+=x;
return;
}
int mid=(l+r)/2;
if(pos<=mid)
{
update_1(u*2,l,mid,pos,x);
}
else
{
update_1(u*2+1,mid+1,r,pos,x);
}
pushup(u);
}
void update_2(int u,int l,int r,int L,int R,int x)
{
if(inrange(l,r,L,R))
{
maketag(u,r-l+1,1ll*x);
}
else if(!outrange(l,r,L,R))
{
int mid=(l+r)/2;
pushdown(u,l,r);
update_2(u*2,l,mid,L,R,x);
update_2(u*2+1,mid+1,r,L,R,x);
pushup(u);
}
}
long long query(int u,int l,int r,int L,int R)
{
if(inrange(l,r,L,R))
{
return w[u];
}
else if(!outrange(l,r,L,R))
{
int mid=(l+r)/2;
pushdown(u,l,r);
return query(u*2,l,mid,L,R)+query(u*2+1,mid+1,r,L,R);
}
else
{
return 0;
}
}
long long ask(int x)
{
long long ans=0;
while(top[x]!=1)
{
ans+=query(1,1,n,dfn[top[x]],dfn[x]);
x=father[top[x]];
}
ans+=query(1,1,n,1,dfn[x]);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n-1; i++)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1; i<=m; i++)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x,a;
scanf("%d%d",&x,&a);
update_1(1,1,n,dfn[x],a);
}
else if(op==2)
{
int x,a;
scanf("%d%d",&x,&a);
update_2(1,1,n,dfn[x],dfn[x]+sz[x]-1,a);
}
else
{
int x;
scanf("%d",&x);
printf("%lld\n",ask(x));
}
}
return 0;
}