#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
struct node
{
int val;
int lazy;
}seg[N<<2];
int n,m,a,b,cnt,type;
vector<int>all[N];
int fa[N],siz[N],top[N],son[N],dep[N],init[N];
int tag[N];
inline void dfs1(int m1)
{
siz[m1]=1;
for(int i:all[m1])
{
if(i==fa[m1])continue;
fa[i]=m1;
dep[i]=dep[m1]+1;
dfs1(i);
siz[m1]+=siz[i];
if(siz[i]>siz[son[m1]])son[m1]=i;
}
}
inline void dfs2(int pos,int gtop)
{
tag[pos]=++cnt;
top[pos]=gtop;
if(son[pos])dfs2(son[pos],gtop);
for(int i:all[pos])
{
if(i==son[pos]||i==fa[pos])continue;
dfs2(i,i);
}
}
inline void Pushdown(int root,int len,int ren)
{
int tmp=seg[root].lazy;
seg[root<<1].val+=tmp*len;
seg[root<<1|1].val+=tmp*ren;
seg[root<<1].lazy+=tmp;
seg[root<<1|1].lazy+=tmp;
seg[root].lazy=0;
}
inline void Build(int L,int R,int root)
{
if(L==R)
{
seg[root].val=init[tag[L]];
return;
}
int mid=L+R>>1;
Build(L,mid,root<<1);
Build(mid+1,R,root<<1|1);
seg[root].val=seg[root<<1].val+seg[root<<1|1].val;
}
inline void Modify(int l,int r,int L,int R,int root,int c)
{
if(L>r||R<l)return;
if(L>=l&&R<=r)
{
seg[root].val+=(R-L+1)*c;
seg[root].lazy+=c;
return;
}
int mid=L+R>>1;
Pushdown(root,mid-L+1,R-mid);
Modify(l,r,L,mid,root<<1,c);
Modify(l,r,mid+1,R,root<<1|1,c);
seg[root].val=seg[root<<1].val+seg[root<<1|1].val;
}
inline int Query(int l,int r,int L,int R,int root)
{
if(L>r||R<l)return 0;
if(L>=l&&R<=r)return seg[root].val;
int mid=L+R>>1;
Pushdown(root,mid-L+1,R-mid);
return Query(l,r,L,mid,root<<1)+Query(l,r,mid+1,R,root<<1|1);
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>init[i];
for(int i=1;i<=n-1;i++)
{
cin>>a>>b;
all[a].push_back(b);
all[b].push_back(a);
}
dfs1(1);
dfs2(1,1);
Build(1,n,1);
while(m--)
{
cin>>type;
if(type==1)
{
cin>>a>>b;
Modify(tag[a],tag[a],1,n,1,b);
}
else if(type==2)
{
cin>>a>>b;
Modify(tag[a],tag[a]+siz[tag[a]]-1,1,n,1,b);
}
else
{
cin>>a;b=1;
int ans=0;
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
ans+=Query(tag[top[a]],tag[a],1,n,1);
a=fa[top[a]];
}
if(dep[a]<dep[b])swap(a,b);
ans+=Query(tag[b],tag[a],1,n,1);
cout<<ans<<'\n';
}
}
return 0;
}