#include <bits/stdc++.h>
using namespace std;
const int K = 17, N = 1 << 17;
int n, q, u, v, op, d[N], id[N], sz[N], root, pId, pa[K][N];
long long val, a[N], st[4 * N + 15], lazy[4 * N + 15];
vector<int> g[N];
void lca_dfs(int p) {
  id[p] = pId++;
  sz[p] = 1;
  for (int i : g[p]) {
    if (i != pa[0][p]) {
      d[i] = d[p] + 1;
      pa[0][i] = p;
      lca_dfs(i);
      sz[p] += sz[i];
    }
  }
}
void lca_init() {
  memset(pa, -1, sizeof(pa));
  lca_dfs(0);
  for (int i = 1; i < K; i++)
    for (int x = 0; x < N; x++)
      if (pa[i - 1][x] != -1) pa[i][x] = pa[i - 1][pa[i - 1][x]];
}
int lca(int u, int v) {
  if (d[u] < d[v]) swap(u, v);
  for (int i = K - 1; i >= 0; i--)
    if (d[u] - (1 << i) >= d[v]) u = pa[i][u];
  if (u == v) return u;
  for (int i = K - 1; i >= 0; i--) {
    if (pa[i][u] != pa[i][v]) {
      u = pa[i][u];
      v = pa[i][v];
    }
  }
  return pa[0][u];
}
void push(int k, int s, int e) {
  if (!lazy[k]) return;
  st[k] += (e - s) * lazy[k];
  if (s + 1 < e) {
    lazy[2 * k] += lazy[k];
    lazy[2 * k + 1] += lazy[k];
  }
  lazy[k] = 0;
}
void upd(int k, int s, int e, int l, int r, long long v) {
  push(k, s, e);
  if (s >= r || e <= l) return;
  if (l <= s && e <= r) {
    lazy[k] += v;
    push(k, s, e);
    return;
  }
  int m = (s + e) / 2;
  upd(2 * k, s, m, l, r, v);
  upd(2 * k + 1, m, e, l, r, v);
  st[k] = st[2 * k] + st[2 * k + 1];
}
long long qry(int k, int s, int e, int l, int r) {
  if (s >= r || e <= l) return 0;
  push(k, s, e);
  if (s >= l && e <= r) return st[k];
  int m = (s + e) / 2;
  return qry(2 * k, s, m, l, r) + qry(2 * k + 1, m, e, l, r);
}
void upd(int l, int r, long long v) { upd(1, 0, n, l, r, v); }
void upd(int p, long long v) { upd(id[p], id[p] + sz[p], v); }
long long qry(int l, int r) { return qry(1, 0, n, l, r); }
long long qry(int p) { return qry(id[p], id[p] + sz[p]); }
bool inside(int u, int v) { return id[v] <= id[u] && id[u] < id[v] + sz[v]; }
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> q;
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lca_init();
  for (int i = 0; i < n; i++) upd(id[i], id[i] + 1, a[i]);
  vector<long long> result;
  while (q--) {
    cin >> op;
    if (op == 1) {
      cin >> root;
      root--;
    } else if (op == 2) {
      cin >> u >> v >> val;
      u--, v--;
      int a = lca(u, v), b = lca(u, root), c = lca(v, root);
      int x = max({make_pair(d[a], a), make_pair(d[b], b), make_pair(d[c], c)})
                  .second;
      if (x == root)
        upd(0, val);
      else if (!inside(root, x))
        upd(x, val);
      else {
        upd(0, val);
        int cur = root;
        for (int i = K - 1; i >= 0; i--)
          if (d[cur] - (1 << i) > d[x]) cur = pa[i][cur];
        upd(cur, -val);
      }
    } else {
      cin >> v;
      v--;
      long long res = 0;
      if (root == v)
        res = qry(0);
      else if (!inside(root, v))
        res = qry(v);
      else {
        res = qry(0);
        int cur = root;
        for (int i = K - 1; i >= 0; i--)
          if (d[cur] - (1 << i) > d[v]) cur = pa[i][cur];
        res -= qry(cur);
      }
      result.push_back(res);
    }
  }
  for (long long i : result) cout << i << "\n";
}
