#include<bits/stdc++.h>
#define int long long
#define mid (pl + pr >> 1)
#define ls (p << 1)
#define rs (p << 1 | 1)
using namespace std;
const int N = 1e5 + 5;
int w[N], dep[N], fa[N], son[N], siz[N], top[N], id[N];
int cnt, n, m;
vector<int> E[N];
void dfs1(int u, int f){
fa[u] = f;
dep[u] = dep[f] + 1;
for(auto k : E[u])
if(k != f)dfs1(k, u);
siz[u] = 1;
for(auto k : E[u]){
if(k == f)continue;
siz[u] += siz[k];
if(siz[k] > siz[son[u]])son[u] = k;
}
return;
}
void dfs2(int u, int f){
top[u] = f;
id[u] = ++ cnt;
if(son[u])dfs2(son[u], f);
for(auto k : E[u]){
if(k == fa[u] || k == son[u])continue;
dfs2(k, k);
}
}
int tree[N << 2], lzy[N << 2];
void build(int p, int pl, int pr){
if(pl == pr){
tree[p] = w[id[pl]];
return;
}
build(ls, pl, mid);
build(rs, mid + 1, pr);
tree[p] = tree[ls] + tree[rs];
return;
}
inline void push_down(int p, int pl, int pr){
if(lzy[p]){
tree[ls] += lzy[p] * (mid - pl + 1);
tree[rs] += lzy[p] * (pr - mid);
lzy[ls] += lzy[p];
lzy[rs] += lzy[p];
lzy[p] = 0;
}
return;
}
void add(int p, int pl, int pr, int l, int r, int k){
if(l > r) swap(l, r);
if(l <= pl && pr <= r){
tree[p] += k * (pr - pl + 1);
lzy[p] += k;
return;
}
push_down(p, pl, pr);
if(mid >= l)add(ls, pl, mid, l, r, k);
if(mid < r)add(rs, mid + 1, pr, l, r, k);
tree[p] = tree[ls] + tree[rs];
return;
}
int que(int p, int pl, int pr, int l, int r){
if (l > r) swap(l, r);
if(l <= pl && pr <= r)return tree[p];
push_down(p, pl, pr);
int res = 0;
if(mid >= l)res += que(ls, pl, mid, l, r);
if(mid < r)res += que(rs, mid + 1, pr, l, r);
tree[p] = tree[ls] + tree[rs];
return res;
}
inline void add_point(int p, int k){
add(1, 1, n, id[p], id[p], k);
return;
}
inline void add_tree(int p, int k){
add(1, 1, n, id[p], id[p] + siz[p] - 1, k);
return;
}
inline int que_road(int p){
int res = 0;
while(p){
res += que(1, 1, n, id[top[p]], id[p]);
p = fa[top[p]];
}
return res;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i ++)
cin >> w[i];
for(int i = 1;i <= n - 1;i ++){
int u, v;cin >> u >> v;
E[u].push_back(v);
E[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
for(int i = 1;i <= m;i ++){
int op; cin >> op;
if(op == 1){
int p, k;cin >> p >> k;
add_point(p, k);
}
if(op == 2){
int p, k;cin >> p >> k;
add_tree(p, k);
}
if(op == 3){
int p;cin >> p;
cout << que_road(p) << '\n';
}
}
for(int i = 1;i <= n;i ++){
cout << siz[i] << ' ';
}
return 0;
}