rt
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls u<<1
#define rs u<<1|1
#define ll long long
#define ii pair<int,int>
#define fi first
#define se second
#define endl '\n'
#define debug(x) cout << #x << ": " << x << endl
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define lb lower_bound
#define ub upper_bound
#define rep(x,start,end) for(int x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
ll rd()
{
ll a=0;int f=0;char p=getchar();
while(!isdigit(p)){f|=p=='-';p=getchar();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=getchar();}
return f?-a:a;
}
const int INF=998244353;
const int P=1e9+7;
const int N=1e6+5;
int siz[N],dep[N],fa[N],mx_son[N];
int dfn[N],pre[N],top[N],tot;
int n,m;
int a[N];
vector<int >G[N];
void dfs1(int u,int f)
{
fa[u]=f;
siz[u]=1;
dep[u]=dep[f]+1;
for(auto v:G[u])
{
if(v==f) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[mx_son[u]])
mx_son[u]=v;
}
}
void dfs2(int u,int f,int t)
{
top[u]=t;
dfn[u]=++tot;
pre[tot]=u;
if(mx_son[u]) dfs2(mx_son[u],u,t);
for(auto v:G[u])
{
if(v==f) continue;
if(v==mx_son[u]) continue;
dfs2(v,u,v);
}
}
ll sum[N];
ll lazy[N];
void pushup(int u){sum[u]=sum[ls]+sum[rs];}
void pushdown(int u,int l,int r)
{
int mid=(l+r)>>1;
lazy[ls]+=lazy[u];
lazy[rs]+=lazy[u];
sum[ls]+=lazy[u]*(mid-l+1);
sum[rs]+=lazy[u]*(r-mid);
lazy[u]=0;
}
void build(int u,int l,int r)
{
if(l==r)
{
sum[u]=a[pre[l]];
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(u);
}
void modify(int u,int l,int r,int L,int R,int x)
{
if(L<=l&&r<=R)
{
lazy[u]+=x;
sum[u]+=(ll)x*(r-l+1);
return ;
}
int mid=(l+r)>>1; pushdown(u,l,r);
if(L<=mid) modify(ls,l,mid,L,R,x);
if(R>mid) modify(rs,mid+1,r,L,R,x);
pushup(u);
}
ll query(int u,int l,int r,int L,int R)
{
if(L<=l&&r<=R) return sum[u];
int mid=(l+r)>>1; pushdown(u,l,r);
ll res=0;
if(L<=mid) res+=query(ls,l,mid,L,R);
if(R>mid) res+=query(rs,mid+1,r,L,R);
pushup(u);
return res;
}
int main()
{
n=rd(); m=rd();
for(int i=1;i<=n;++i) a[i]=rd();
for(int i=1;i<n;++i)
{
int x=rd();
int y=rd();
G[x].push_back(y);
G[y].push_back(x);
}
dfs1(1,0);
dfs2(1,0,1);
build(1,1,n);
while(m--)
{
int opt=rd();
if(opt==1)
{
int x=rd();
int y=rd();
modify(1,1,n,dfn[x],dfn[x],y);
}
if(opt==2)
{
int x=rd();
int y=rd();
modify(1,1,n,dfn[x],dfn[x]+siz[x]-1,y);
}
if(opt==3)
{
int x=rd();
ll res=0;
while(x)
{
res+=query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
cout<<res<<endl;
}
}
return 0;
}