#include<bits/stdc++.h>
#define ll long long
#define N 500005
using namespace std;
ll n,m,cnt,tot,a[N],id[N],fa[N],top[N],dep[N],pre[N],tree[N],lazy[N],head[N],hson[N],size[N];
struct Edge
{
ll to,next;
}G[N];
void add(ll x,ll y)
{
G[++cnt].to=y,G[cnt].next=head[x],head[x]=cnt;
}
void pushup(ll q)
{
tree[q]=tree[q<<1]+tree[q<<1|1];
}
void pushdown(ll q,ll l,ll r)
{
if(lazy[q])
{
tree[q<<1]=tree[q<<1]+lazy[q]*l;
tree[q<<1|1]=tree[q<<1|1]+lazy[q]*r;
lazy[q<<1]=lazy[q<<1]+lazy[q];
lazy[q<<1|1]=lazy[q<<1|1]+lazy[q];
lazy[q]=0;
}
}
void build(ll q,ll l,ll r)
{
if(l==r)
{
tree[q]=a[pre[l]];
return ;
}
ll mid=(l+r)>>1;
build(q<<1,l,mid),build(q<<1|1,mid+1,r);
pushup(q);
}
void update(ll q,ll num,ll l,ll r,ll ql,ll qr)
{
if(l>=ql&&r<=qr)
{
tree[q]=tree[q]+num*(r-l+1);
lazy[q]=lazy[q]+num;
return ;
}
ll mid=(l+r)>>1;
pushdown(q,mid-l+1,r-mid);
if(mid>=ql)
update(q<<1,num,l,mid,ql,qr);
if(mid+1<=qr)
update(q<<1|1,num,mid+1,r,ql,qr);
pushup(q);
}
ll query(ll q,ll l,ll r,ll ql,ll qr)
{
if(l>=ql&&r<=qr)
return tree[q];
ll ans=0,mid=(l+r)>>1;
pushdown(q,mid-l+1,r-mid);
if(mid>=ql)
ans=ans+query(q<<1,l,mid,ql,qr);
if(mid+1<=qr)
ans=ans+query(q<<1|1,mid+1,r,ql,qr);
pushup(q);
return ans;
}
void dfs1(ll x,ll y)
{
fa[x]=y,size[x]=1;
for(ll i=head[x];i!=0;i=G[i].next)
{
ll f=G[i].to;
if(fa[x]!=f)
{
dep[f]=dep[x]+1;dfs1(f,x);
if(hson==0||size[hson[x]]<size[f])
hson[x]=f;size[x]=size[x]+size[f];
}
}
}
void dfs2(ll x,ll y)
{
top[x]=y,id[x]=++tot,pre[tot]=x;
if(hson[x]==0) return ;
dfs2(hson[x],y);
for(ll i=head[x];i!=0;i=G[i].next)
{
ll f=G[i].to;
if(f!=fa[x]&&f!=hson[x])
dfs2(f,f);
}
}
void first_operation()
{
ll u,v;cin>>u>>v;
update(1,v,1,n,id[u],id[u]);
}
void second_operation()
{
ll u,v;cin>>u>>v;
update(1,v,1,n,id[u],id[u]+size[u]-1);
}
void third_operation()
{
ll ans=0,u,v=top[u];cin>>u;
while(v!=1)
{
ans=ans+query(1,1,n,id[v],id[u]);
u=fa[v],v=top[u];
}
ans=ans+query(1,1,n,id[1],id[u]);
cout<<ans<<endl;
}
signed main()
{
cin>>n>>m;
for(ll i=1;i<=n;i++)
cin>>a[i];
for(ll i=1;i<n;i++)
{
ll u,v;cin>>u>>v;
add(u,v),add(v,u);
}
dep[1]=1;dfs1(1,0);dfs2(1,1);build(1,1,n);
for(ll i=1;i<=m;i++)
{
ll q;cin>>q;
if(q==1)
first_operation();
if(q==2)
second_operation();
if(q==3)
third_operation();
}
return 0;
}