#include <bits/stdc++.h>
using namespace std;
int n, m, tot, nrt = 1, cnt, tt, dfn[100005], nw[100005], hd[100005],
               val[100005], to[200005], nxt[200005], fa[100005], ms[100005],
               sz[100005], top[100005], dep[100005], id[100005], ff[100005][20];
struct node {
  int l, r;
  long long sum, add;
} t[400005];
int read() {
  int x = 0, fl = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') fl = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getchar();
  }
  return x * fl;
}
void dfs1(int x, int f) {
  dfn[x] = ++tt;
  sz[x] = 1;
  int mx = -1;
  for (int i = hd[x]; i; i = nxt[i]) {
    int y = to[i];
    if (y == f) continue;
    ff[y][0] = x;
    for (int j = 1; j <= 19; j++) ff[y][j] = ff[ff[y][j - 1]][j - 1];
    dep[y] = dep[x] + 1;
    fa[y] = x;
    dfs1(y, x);
    if (sz[y] > mx) {
      mx = sz[y];
      ms[x] = y;
    }
    sz[x] += sz[y];
  }
  return;
}
void dfs2(int x, int tp) {
  top[x] = tp;
  id[x] = ++cnt;
  nw[cnt] = val[x];
  if (!ms[x]) return;
  dfs2(ms[x], tp);
  for (int i = hd[x]; i; i = nxt[i]) {
    int y = to[i];
    if (y == fa[x] || y == ms[x]) continue;
    dfs2(y, y);
  }
  return;
}
void add(int x, int y) {
  tot++;
  to[tot] = y;
  nxt[tot] = hd[x];
  hd[x] = tot;
  return;
}
void push_up(int p) {
  t[p].sum = t[(p << 1)].sum + t[(p << 1 | 1)].sum;
  return;
}
void push_down(int p) {
  if (!t[p].add) return;
  t[(p << 1)].add += t[p].add;
  t[(p << 1 | 1)].add += t[p].add;
  t[(p << 1)].sum += t[p].add * (long long)(t[(p << 1)].r - t[(p << 1)].l + 1);
  t[(p << 1 | 1)].sum +=
      t[p].add * (long long)(t[(p << 1 | 1)].r - t[(p << 1 | 1)].l + 1);
  t[p].add = 0;
  return;
}
void build(int p, int l0, int r0) {
  t[p].l = l0;
  t[p].r = r0;
  if (l0 == r0) {
    t[p].sum = (long long)nw[l0];
    return;
  }
  int mid = (t[p].l + t[p].r) >> 1;
  build((p << 1), l0, mid);
  build((p << 1 | 1), mid + 1, r0);
  push_up(p);
  return;
}
void update(int p, int l0, int r0, int d) {
  if (l0 <= t[p].l && t[p].r <= r0) {
    t[p].add += (long long)d;
    t[p].sum += 1ll * d * (t[p].r - t[p].l + 1);
    return;
  }
  push_down(p);
  int mid = (t[p].l + t[p].r) >> 1;
  if (l0 <= mid) update((p << 1), l0, r0, d);
  if (r0 > mid) update((p << 1 | 1), l0, r0, d);
  push_up(p);
  return;
}
long long query(int p, int l0, int r0) {
  if (l0 <= t[p].l && t[p].r <= r0) return t[p].sum;
  push_down(p);
  int mid = (t[p].l + t[p].r) >> 1;
  long long s = 0ll;
  if (l0 <= mid) s = s + query((p << 1), l0, r0);
  if (r0 > mid) s = s + query((p << 1 | 1), l0, r0);
  return s;
}
int ask_lca(int x, int y) {
  if (x == y) return x;
  if (dfn[x] > dfn[y]) swap(x, y);
  for (int i = 19; i >= 0; i--)
    if (dfn[ff[y][i]] > dfn[x]) y = ff[y][i];
  return ff[y][0];
}
int calc_lca(int x, int y) {
  int p1 = ask_lca(x, y), p2 = ask_lca(x, nrt), p3 = ask_lca(y, nrt);
  if (dep[p1] > dep[p2] && dep[p1] > dep[p3])
    return p1;
  else if (dep[p2] > dep[p1] && dep[p2] > dep[p3])
    return p2;
  else
    return p3;
}
void modify1(int x, int d) {
  if (x == nrt) {
    update(1, 1, n, d);
    return;
  }
  int u = x, v = nrt;
  for (int i = 19; i >= 0; i--)
    if (dfn[ff[v][i]] > dfn[u]) v = ff[v][i];
  if (id[v] >= 1) update(1, 1, id[v] - 1, d);
  if (id[v] + sz[v] <= n) update(1, id[v] + sz[v], n, d);
  return;
}
void modify2(int x, int d) {
  update(1, id[x], id[x] + sz[x] - 1, d);
  return;
}
long long ask1(int x) {
  if (x == nrt) return query(1, 1, n);
  int u = x, v = nrt;
  for (int i = 19; i >= 0; i--)
    if (dfn[ff[v][i]] > dfn[u]) v = ff[v][i];
  long long s = 0ll;
  if (id[v] >= 1) s = s + query(1, 1, id[v] - 1);
  if (id[v] + sz[v] <= n) s = s + query(1, id[v] + sz[v], n);
  return s;
}
long long ask2(int x) { return query(1, id[x], id[x] + sz[x] - 1); }
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= n; i++) val[i] = read();
  for (int i = 1; i <= n - 1; i++) {
    int x = read(), y = read();
    add(x, y);
    add(y, x);
  }
  dfs1(1, 0);
  dfs2(1, 1);
  build(1, 1, n);
  while (m--) {
    int opt = read();
    if (opt == 1)
      nrt = read();
    else if (opt == 2) {
      int x = read(), y = read(), d = read();
      int p = calc_lca(x, y);
      if (id[nrt] >= id[p] && id[nrt] <= id[p] + sz[p] - 1)
        modify1(p, d);
      else
        modify2(p, d);
    } else {
      int x = read();
      if (id[nrt] >= id[x] && id[nrt] <= id[x] + sz[x] - 1)
        printf("%lld\n", ask1(x));
      else
        printf("%lld\n", ask2(x));
    }
  }
  return 0;
}
