#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector")
using namespace std;
const double eps = 1e-7;
long long n, q;
long long head[200000];
long long dfn;
long long inde;
long long a[200000];
long long ad[200000 << 2];
long long tree[200000 << 2];
long long root;
struct edge {
  long long to;
  long long next;
} e[200000 << 1];
void add(long long u, long long v) {
  e[++inde].to = v;
  e[inde].next = head[u];
  head[u] = inde;
}
long long fa[200000];
long long siz[200000];
long long top[200000];
long long dep[200000];
long long son[200000];
long long seg[200000];
long long rev[200000];
void dfs1(long long x, long long f) {
  siz[x] = 1;
  dep[x] = dep[f] + 1;
  fa[x] = f;
  for (long long i = head[x]; i; i = e[i].next) {
    long long v = e[i].to;
    if (v == f) {
      continue;
    }
    dfs1(v, x);
    siz[x] += siz[v];
    if (siz[son[x]] < siz[v]) {
      son[x] = v;
    }
  }
}
void dfs2(long long x, long long f) {
  if (son[x]) {
    seg[son[x]] = ++dfn;
    top[son[x]] = top[x];
    rev[dfn] = son[x];
    dfs2(son[x], x);
  }
  for (long long i = head[x]; i; i = e[i].next) {
    long long v = e[i].to;
    if (!top[v]) {
      seg[v] = ++dfn;
      top[v] = v;
      rev[dfn] = v;
      dfs2(v, x);
    }
  }
}
long long lca(long long x, long long y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] >= dep[top[y]]) {
      x = fa[top[x]];
    } else {
      y = fa[top[y]];
    }
  }
  if (dep[x] < dep[y]) {
    return x;
  } else {
    return y;
  }
}
long long findd(long long xi, long long rt) {
  long long x = xi;
  long long y = rt;
  while (top[x] != top[y]) {
    if (dep[top[x]] >= dep[top[y]]) {
      if (fa[top[x]] == xi) {
        return top[x];
      }
      x = fa[top[x]];
    } else {
      if (fa[top[y]] == xi) {
        return top[y];
      }
      y = fa[top[y]];
    }
  }
  return son[xi];
}
long long getroot(long long u, long long v) {
  long long x = lca(v, u);
  long long y = lca(v, root);
  long long z = lca(u, root);
  if (dep[y] > dep[x]) {
    x = y;
  }
  if (dep[z] > dep[x]) {
    x = z;
  }
  return x;
}
void pushup(long long id) { tree[id] = tree[id << 1] + tree[id << 1 | 1]; }
void down(long long l, long long r, long long id) {
  long long mid = (l + r) >> 1;
  if (ad[id]) {
    ad[id << 1] += ad[id];
    ad[id << 1 | 1] += ad[id];
    tree[id << 1] += ad[id] * (mid - l + 1);
    tree[id << 1 | 1] += ad[id] * (r - mid);
    ad[id] = 0;
  }
}
void build(long long l, long long r, long long id) {
  if (l == r) {
    tree[id] = a[rev[l]];
    return;
  }
  long long mid = (l + r) >> 1;
  build(l, mid, id << 1);
  build(mid + 1, r, id << 1 | 1);
  pushup(id);
}
void up(long long L, long long R, long long l, long long r, long long c,
        long long id) {
  if (L <= l && r <= R) {
    tree[id] += c * (r - l + 1);
    ad[id] += c;
    return;
  }
  long long mid = (l + r) >> 1;
  down(l, r, id);
  if (L <= mid) {
    up(L, R, l, mid, c, id << 1);
  }
  if (R > mid) {
    up(L, R, mid + 1, r, c, id << 1 | 1);
  }
  pushup(id);
}
long long ask(long long L, long long R, long long l, long long r,
              long long id) {
  if (L <= l && r <= R) {
    return tree[id];
  }
  long long mid = (l + r) >> 1;
  down(l, r, id);
  long long ans = 0;
  if (L <= mid) {
    ans += ask(L, R, l, mid, id << 1);
  }
  if (R > mid) {
    ans += ask(L, R, mid + 1, r, id << 1 | 1);
  }
  return ans;
}
void f3(long long x) {
  if (x == root) {
    cout << ask(1, n, 1, n, 1) << endl;
  } else if (x == lca(x, root)) {
    long long tuo = findd(x, root);
    cout << ask(1, n, 1, n, 1) - ask(seg[tuo], seg[tuo] + siz[tuo] - 1, 1, n, 1)
         << endl;
  } else {
    cout << ask(seg[x], seg[x] + siz[x] - 1, 1, n, 1) << endl;
    ;
  }
}
void f2(long long x, long long y, long long c) {
  x = getroot(x, y);
  if (x == root) {
    up(1, n, 1, n, c, 1);
  } else if (x == lca(x, root)) {
    long long tuo = findd(x, root);
    up(1, n, 1, n, c, 1);
    up(seg[tuo], seg[tuo] + siz[tuo] - 1, 1, n, -c, 1);
  } else {
    up(seg[x], seg[x] + siz[x] - 1, 1, n, c, 1);
  }
}
long long x;
long long u;
long long v;
long long c;
signed main() {
  root = 1;
  scanf("%lld%lld", &n, &q);
  for (long long i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
  }
  for (long long i = 1; i < n; i++) {
    scanf("%lld%lld", &u, &v);
    add(u, v);
    add(v, u);
  }
  dfs1(1, 0);
  dfn = seg[1] = top[1] = rev[1] = 1;
  dfs2(1, 0);
  build(1, dfn, 1);
  while (q--) {
    scanf("%lld", &u);
    if (u == 1) {
      scanf("%lld", &v);
      root = v;
    } else if (u == 2) {
      scanf("%lld%lld%lld", &u, &v, &x);
      f2(u, v, x);
    } else {
      scanf("%lld", &v);
      f3(v);
    }
  }
  return 0;
}
