#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[100010],eid=1,head[200010],id[100010],vis[100010],rev[100010],op,x,A,Size[100010],son[100010],fa[100010],top[100010],tot,lazy[800010];
vector<pair<int,int>> G[100010];
struct node
{
int v,next;
}e[200010];
struct edge
{
int sum,l,r;
}C[800010];
inline void insert(int u,int v)
{
e[eid].v=v;
e[eid].next=head[u];
head[u]=eid++;
}
inline void dfs(int u,int father)
{
Size[u]=1;
fa[u]=father;
int maxn=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==father)
{
continue;
}
dfs(v,u);
Size[u]+=Size[v];
if(Size[v]>maxn)
{
maxn=Size[v];
son[u]=v;
}
G[u].push_back({-Size[v],v});
}
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
G[v].push_back({-Size[u],u});
}
sort(G[u].begin(),G[u].end());
}
inline void dfs1(int u,int father)
{
if(vis[u])return;
vis[u]=1;
if(u==son[fa[u]])
{
top[u]=top[fa[u]];
}
else
{
top[u]=u;
}
rev[++tot]=u;
id[u]=tot;
for(auto now:G[u])
{
int v=now.second;
if(v==father)
{
continue;
}
dfs1(v,u);
}
}
inline void pushdown(int id)
{
if(lazy[id])
{
lazy[id<<1]+=lazy[id];
lazy[id<<1|1]+=lazy[id];
int mid=C[id].l+C[id].r>>1,l=C[id].l,r=C[id].r;
C[id<<1].sum+=lazy[id]*(mid-l+1);
C[id<<1|1].sum+=lazy[id]*(r-mid);
lazy[id]=0;
}
}
inline void build(int id,int l,int r)
{
C[id].l=l;
C[id].r=r;
if(l==r)
{
C[id].sum=a[rev[l]];
return;
}
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
C[id].sum=C[id<<1].sum+C[id<<1|1].sum;
}
inline void update(int id,int l,int r,int v)
{
if(l<=C[id].l&&C[id].r<=r)
{
C[id].sum+=v*(C[id].r-C[id].l+1);
lazy[id]+=v;
return;
}
pushdown(id);
int mid=C[id].l+C[id].r>>1;
if(l<=mid)
{
update(id<<1,l,r,v);
}
if(mid<r)
{
update(id<<1|1,l,r,v);
}
C[id].sum=C[id<<1].sum+C[id<<1|1].sum;
}
inline int Query(int id,int x,int y)
{
if(x<=C[id].l&&C[id].r<=y)
{
return C[id].sum;
}
pushdown(id);
int mid=C[id].l+C[id].r>>1,ans=0;
if(x<=mid)
{
ans+=Query(id<<1,x,y);
}
if(y>mid)
{
ans+=Query(id<<1|1,x,y);
}
return ans;
}
inline int query(int x)
{
int res=0,pre=x,y=top[x];
res=Query(1,id[x],id[y]);
pre=fa[y];
while(pre)
{
res+=Query(1,id[pre],id[top[pre]]);
pre=fa[top[pre]];
}
return res;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
insert(u,v);
insert(v,u);
}
dfs(1,0);
dfs1(1,0);
build(1,1,n);
while(m--)
{
cin>>op>>x;
if(op==1)
{
cin>>A;
update(1,id[x],id[x],A);
}
if(op==2)
{
cin>>A;
update(1,id[x],id[x]+Size[x]-1,A);
}
if(op==3)
{
cout<<query(x)<<"\n";
}
}
}