#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int ret = 0;
  bool fla = 0;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') {
    fla = 1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    ret = ret * 10 + ch - '0';
    ch = getchar();
  }
  return fla ? -ret : ret;
}
struct edge {
  int to, ne;
} e[200005 * 2];
int n, m, rt, num, ecnt, fa[200005], dep[200005], siz[200005], son[200005],
    top[200005], val[200005], in[200005], out[200005], dfn[200005],
    head[200005];
long long t[200005 * 8], mark[200005 * 8];
int st[200005][22];
void add(int x, int y) {
  e[++ecnt] = (edge){y, head[x]};
  head[x] = ecnt;
}
void dfs(int x) {
  dep[x] = dep[fa[x]] + 1;
  siz[x] = 1;
  st[x][0] = fa[x];
  for (int i = 1; i <= 16; ++i) st[x][i] = st[st[x][i - 1]][i - 1];
  for (int i = head[x]; i; i = e[i].ne) {
    int dd = e[i].to;
    if (dd == fa[x]) continue;
    fa[dd] = x;
    dfs(dd);
    siz[x] += siz[dd];
    if (!son[x] || siz[dd] > siz[son[x]]) son[x] = dd;
  }
}
void df2(int x, int tp) {
  dfn[++num] = x;
  in[x] = num;
  top[x] = tp;
  if (son[x]) df2(son[x], tp);
  for (int i = head[x]; i; i = e[i].ne) {
    int dd = e[i].to;
    if (dd == fa[x] || dd == son[x]) continue;
    df2(dd, dd);
  }
  out[x] = num;
}
void upda(int x) { t[x] = t[x << 1] + t[x << 1 | 1]; }
void pd(int v, int len1, int len2) {
  if (mark[v] != 0) {
    mark[v << 1] += mark[v];
    mark[v << 1 | 1] += mark[v];
    t[v << 1] += (long long)mark[v] * len1;
    t[v << 1 | 1] += (long long)mark[v] * len2;
    mark[v] = 0;
  }
}
void build(int l, int r, int v) {
  if (l == r) {
    t[v] = val[dfn[l]];
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, v << 1);
  build(mid + 1, r, v << 1 | 1);
  upda(v);
}
void change(int l, int r, int v, int x, int y, int z) {
  if (r < x || y < l) return;
  if (x <= l && r <= y) {
    t[v] += (long long)(r - l + 1) * z;
    mark[v] += (long long)z;
    return;
  }
  int mid = (l + r) >> 1;
  pd(v, mid - l + 1, r - mid);
  change(l, mid, v << 1, x, y, z);
  change(mid + 1, r, v << 1 | 1, x, y, z);
  upda(v);
}
long long ask(int l, int r, int v, int x, int y) {
  if (r < x || y < l) return 0;
  if (x <= l && r <= y) return t[v];
  int mid = (l + r) >> 1;
  pd(v, mid - l + 1, r - mid);
  return ask(l, mid, v << 1, x, y) + ask(mid + 1, r, v << 1 | 1, x, y);
}
void find(int l, int r, int v) {
  if (l == r) {
    printf("%I64d ", t[v]);
    return;
  }
  int mid = (l + r) >> 1;
  pd(v, mid - l + 1, r - mid);
  find(l, mid, v << 1), find(mid + 1, r, v << 1 | 1);
}
int LCA(int x, int y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    x = fa[top[x]];
  }
  return dep[x] < dep[y] ? x : y;
}
int get(int x) {
  int y = rt;
  for (int i = 16; i >= 0; --i)
    if (dep[st[y][i]] > dep[x]) y = st[y][i];
  return y;
}
bool pdin(int x, int y) { return in[y] <= in[x] && out[x] <= out[y]; }
int main() {
  n = read(), m = read();
  for (int i = 1; i <= n; ++i) val[i] = read();
  for (int i = 1, x, y; i < n; ++i)
    x = read(), y = read(), add(x, y), add(y, x);
  rt = 1;
  dfs(1);
  df2(1, 1);
  build(1, n, 1);
  for (int i = 1, op, x, y, z; i <= m; ++i) {
    op = read(), x = read();
    if (op == 1) {
      rt = x;
    } else if (op == 2) {
      y = read();
      z = read();
      int lca = LCA(x, y) ^ LCA(rt, x) ^ LCA(rt, y);
      if (lca == rt)
        change(1, n, 1, 1, n, z);
      else if (in[lca] <= in[rt] && out[rt] <= out[lca]) {
        int xx = get(lca);
        change(1, n, 1, 1, n, z);
        change(1, n, 1, in[xx], out[xx], -z);
      } else {
        change(1, n, 1, in[lca], out[lca], z);
      }
    } else {
      if (x == rt) {
        printf("%I64d\n", ask(1, n, 1, 1, n));
      } else if (in[x] <= in[rt] && out[rt] <= out[x]) {
        int xx = get(x);
        printf("%I64d\n", ask(1, n, 1, 1, n) - ask(1, n, 1, in[xx], out[xx]));
      } else
        printf("%I64d\n", ask(1, n, 1, in[x], out[x]));
    }
  }
  return 0;
}
