rt,0pts,全WA
#include<bits/stdc++.h>
#define fi first
#define se second
#define int long long
#define pb push_back
#define lson(x) x<<1
#define P pair<int,int>
#define rson(x) x<<1|1
#define len(x,y) (y-x+1)
#define mid(x,y) ((x+y)>>1)
#define mp(x,y) {min(x,y),max(x,y)}
using namespace std;
const int N=5e5+9;
int n,q,b[N],a[N],cnt;
struct Tree{
int lt[N],rt[N],sum[N],lazy[N];
inline void push_up(int x){
sum[x]=sum[lson(x)]+sum[rson(x)];
return void();
}
inline void push_down(int x){
if(lazy[x]){
sum[lson(x)]+=len(lt[lson(x)],rt[lson(x)])*lazy[x];
sum[rson(x)]+=len(lt[rson(x)],rt[rson(x)])*lazy[x];
lazy[lson(x)]+=lazy[x];
lazy[rson(x)]+=lazy[x];
lazy[x]=0;
}
}
inline void Build(int x,int l,int r){
lt[x]=l;rt[x]=r;
if(l==r){sum[x]=a[l];return void();}
Build(lson(x),l,mid(l,r));
Build(rson(x),mid(l,r)+1,r);
push_up(x);
}
inline void change(int x,P pos,int num){
if(lt[x]>=pos.fi && rt[x]<=pos.se){
lazy[x]+=num;
sum[x]+=len(lt[x],rt[x])*num;
return void();
}
push_down(x);
if(pos.fi<=mid(lt[x],rt[x]))
change(lson(x),pos,num);
if(pos.se>mid(lt[x],rt[x]))
change(rson(x),pos,num);
push_up(x);
return void();
}
inline int query(int x,P pos){
if(lt[x]>=pos.fi && rt[x]<=pos.se)
return sum[x];
push_down(x);
int Sum=0;
if(pos.fi<=mid(lt[x],rt[x]))
Sum+=query(lson(x),pos);
if(pos.se>mid(lt[x],rt[x]))
Sum+=query(rson(x),pos);
return Sum;
}
}tree;
struct node{
int siz[N],hson[N],dfn[N];
int fa[N],top[N];
vector<int>e[N];
inline void dfs1(int x,int fat){
fa[x]=fat;
siz[x]=1;hson[x]=-1;
for(auto i:e[x]){
if(i==fat) continue;
dfs1(i,x);
siz[x]+=siz[i];
if(hson[x]==-1 || siz[i]>siz[hson[x]])
hson[x]=i;
}
}
inline void dfs2(int x,int tp){
top[x]=tp;dfn[x]=++cnt;
if(hson[x]!=-1) dfs2(hson[x],tp);
for(auto i:e[x])
if(i!=fa[x] && i!=hson[x])
dfs2(i,i);
}
inline void change(int lt,int rt,int num){
tree.change(1,{lt,rt},num);
return void();
}
inline int Getans(int x){
int sum=0,pos=x;
while(pos!=1){
sum+=tree.query(1,mp(dfn[pos],dfn[top[pos]]));
pos=fa[top[pos]];
}
return sum;
}
}seg;
signed main(){
cin>>n>>q;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1,u,v;i<n;i++)
cin>>u>>v,
seg.e[u].pb(v),
seg.e[v].pb(u);
seg.dfs1(1,1);
seg.dfs2(1,1);
for(int i=1;i<=n;i++)
b[i]=a[seg.dfn[i]];
for(int i=1;i<=n;i++)
a[i]=b[i];
tree.Build(1,1,n);
int opt,x,y;
while(q--){
cin>>opt>>x;
if(opt==1){
cin>>y;
seg.change(seg.dfn[x],seg.dfn[x],y);
continue;
}else if(opt==2){
cin>>y;
seg.change(seg.dfn[x],seg.dfn[x]+seg.siz[x]-1,y);
continue;
}else{
cout<<seg.Getans(x)<<endl;
}
}
return 0;
}
/*
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
6
9
13
*/