#include <bits/stdc++.h>
const int S = 200003;
int n, m, h[S], nx[S], v[S], eg = 1, s[S], e[S], _ = 0, t[S], fa[S], dep[S],
                             f[S], rk[S], root, a[S];
inline void egadd(int uu, int vv) {
  nx[++eg] = h[uu];
  h[uu] = eg;
  v[eg] = vv;
}
void dfs_1(int x) {
  s[x] = 1;
  for (int i = h[x]; i; i = nx[i])
    if (v[i] != fa[x]) {
      fa[v[i]] = x;
      dep[v[i]] = dep[x] + 1;
      dfs_1(v[i]);
      s[x] += s[v[i]];
      if (s[e[x]] < s[v[i]]) e[x] = v[i];
    }
}
void dfs_2(int x, int top) {
  f[x] = ++_;
  rk[_] = x;
  t[x] = top;
  if (!e[x]) return;
  dfs_2(e[x], top);
  for (int i = h[x]; i; i = nx[i])
    if (v[i] != fa[x] && v[i] != e[x]) dfs_2(v[i], v[i]);
}
long long sg[S << 2], add[S << 2];
inline void down(int w, int l, int r) {
  if (add[w]) {
    int mid = (l + r) >> 1;
    add[(w << 1)] += add[w];
    add[(w << 1) | 1] += add[w];
    sg[(w << 1)] += add[w] * (mid - l + 1);
    sg[(w << 1) | 1] += add[w] * (r - mid);
    add[w] = 0;
  }
}
inline void sgadd(int l, int r, int ll, int rr, int k, int w) {
  if (ll <= l && r <= rr) {
    sg[w] += 1ll * (r - l + 1) * k;
    add[w] += k;
    return;
  }
  int mid = (l + r) >> 1;
  down(w, l, r);
  if (ll <= mid) sgadd(l, mid, ll, rr, k, (w << 1));
  if (rr > mid) sgadd(mid + 1, r, ll, rr, k, (w << 1) | 1);
  sg[w] = sg[(w << 1)] + sg[(w << 1) | 1];
}
inline void sgb(int l, int r, int w) {
  if (l == r) {
    sg[w] = a[rk[l]];
    return;
  }
  int mid = (l + r) >> 1;
  sgb(l, mid, (w << 1));
  sgb(mid + 1, r, (w << 1) | 1);
  sg[w] = sg[(w << 1)] + sg[(w << 1) | 1];
}
inline long long sgcal(int l, int r, int ll, int rr, int w) {
  if (ll <= l && r <= rr) return sg[w];
  int mid = (l + r) >> 1;
  down(w, l, r);
  long long ret = 0;
  if (ll <= mid) ret += sgcal(l, mid, ll, rr, (w << 1));
  if (rr > mid) ret += sgcal(mid + 1, r, ll, rr, (w << 1) | 1);
  return ret;
}
inline int hang(int x, int y) {
  while (true) {
    if (fa[t[y]] == x) return t[y];
    if (f[t[y]] <= f[x] && f[x] <= f[y]) return e[x];
    y = fa[t[y]];
  }
}
inline int lca(int x, int y) {
  while (t[x] != t[y]) {
    if (dep[t[x]] < dep[t[y]]) x ^= y ^= x ^= y;
    x = fa[t[x]];
  }
  if (x == y) return x;
  if (dep[x] > dep[y])
    return y;
  else
    return x;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", a + i);
  for (int i = 1; i < n; i++) {
    int uu, vv;
    scanf("%d%d", &uu, &vv);
    egadd(uu, vv);
    egadd(vv, uu);
  }
  root = 1;
  dfs_1(1);
  dfs_2(1, 1);
  sgb(1, n, 1);
  int o, x, y, z;
  while (m--) {
    scanf("%d%d", &o, &x);
    if (o == 1)
      root = x;
    else if (o == 2) {
      scanf("%d%d", &y, &z);
      int o1, o2, o3;
      o1 = lca(x, y);
      if (o1 != root && (f[o1] <= f[root] && f[root] <= f[o1] + s[o1] - 1)) {
        o2 = lca(x, root);
        o3 = lca(y, root);
        if (dep[o1] < dep[o2]) o1 = o2;
        if (dep[o1] < dep[o3]) o1 = o3;
        if (o1 == root)
          sgadd(1, n, 1, n, z, 1);
        else {
          o2 = hang(o1, root);
          sgadd(1, n, 1, n, z, 1);
          sgadd(1, n, f[o2], f[o2] + s[o2] - 1, -z, 1);
        }
      } else if (o1 == root)
        sgadd(1, n, 1, n, z, 1);
      else
        sgadd(1, n, f[o1], f[o1] + s[o1] - 1, z, 1);
    } else {
      if (x != root && (f[x] <= f[root] && f[root] <= f[x] + s[x] - 1)) {
        int o = hang(x, root);
        printf("%lld\n",
               sgcal(1, n, 1, n, 1) - sgcal(1, n, f[o], f[o] + s[o] - 1, 1));
      } else if (x == root)
        printf("%lld\n", sgcal(1, n, 1, n, 1));
      else
        printf("%lld\n", sgcal(1, n, f[x], f[x] + s[x] - 1, 1));
    }
  }
  return 0;
}
