#include <bits/stdc++.h>
using namespace std;
const int mod1 = 1e9 + 7, mod2 = 998244353, maxn = 1e5 + 5, maxlog = 20, K = 26;
const long long infll = 1e18;
const double pi = acos(-1);
long long n, m, q, root, tin[maxn], tout[maxn], euler[maxn << 1], st[maxn << 3],
    lazy[maxn << 3], a[maxn], par[maxn][maxlog], timer = 0, h[maxn];
vector<long long> gr[maxn];
void dfs(long long u, long long pa) {
  tin[u] = ++timer;
  par[u][0] = pa;
  euler[timer] = a[u];
  for (long long i = 1; i < maxlog; ++i) {
    par[u][i] = par[par[u][i - 1]][i - 1];
  }
  for (auto v : gr[u]) {
    if (v == pa) continue;
    h[v] = h[u] + 1;
    dfs(v, u);
  }
  tout[u] = ++timer;
  euler[timer] = a[u];
}
long long get_par(long long u, long long dist) {
  for (long long i = 0; i < maxlog; ++i) {
    if ((dist >> i) & 1) {
      u = par[u][i];
    }
  }
  return u;
}
long long lca(long long u, long long v) {
  if (h[u] != h[v]) {
    if (h[u] < h[v]) swap(u, v);
    u = get_par(u, h[u] - h[v]);
  }
  if (u == v) return u;
  for (long long i = maxlog - 1; i >= 0; --i) {
    if (par[u][i] != par[v][i]) {
      u = par[u][i];
      v = par[v][i];
    }
  }
  return par[u][0];
}
void build(long long id, long long l, long long r) {
  if (l > r) return;
  if (l == r) {
    st[id] = euler[l];
    return;
  }
  long long mid = (l + r) >> 1;
  build(id << 1, l, mid);
  build(id << 1 | 1, mid + 1, r);
  st[id] = st[id << 1] + st[id << 1 | 1];
}
void push_to_child(long long id, long long l, long long r) {
  if (lazy[id] != 0) {
    st[id] += (r - l + 1) * lazy[id];
    if (l != r) {
      lazy[id << 1] += lazy[id];
      lazy[id << 1 | 1] += lazy[id];
    }
    lazy[id] = 0;
  }
}
void update(long long id, long long l, long long r, long long ql, long long qr,
            long long val) {
  push_to_child(id, l, r);
  if (l > r || ql > r || qr < l) return;
  if (ql <= l && r <= qr) {
    st[id] += (r - l + 1) * val;
    if (l != r) {
      lazy[id << 1] += val;
      lazy[id << 1 | 1] += val;
    }
    return;
  }
  long long mid = (l + r) >> 1;
  update(id << 1, l, mid, ql, qr, val);
  update(id << 1 | 1, mid + 1, r, ql, qr, val);
  st[id] = st[id << 1] + st[id << 1 | 1];
}
long long get_sum(long long id, long long l, long long r, long long ql,
                  long long qr) {
  if (l > r || ql > r || qr < l) return 0;
  push_to_child(id, l, r);
  if (ql <= l && r <= qr) return st[id];
  long long mid = (l + r) >> 1;
  return get_sum(id << 1, l, mid, ql, qr) +
         get_sum(id << 1 | 1, mid + 1, r, ql, qr);
}
void solve() {
  cin >> n >> q;
  root = 1;
  for (long long i = 1; i <= n; ++i) cin >> a[i];
  for (long long i = 1; i < n; ++i) {
    int u, v;
    cin >> u >> v;
    gr[u].push_back(v);
    gr[v].push_back(u);
  }
  dfs(1, 0);
  build(1, 1, 2 * n);
  while (q--) {
    long long type;
    cin >> type;
    if (type == 1) {
      long long v;
      cin >> v;
      root = v;
    } else if (type == 2) {
      long long u, v, val;
      cin >> u >> v >> val;
      long long x = lca(u, v);
      if (lca(x, root) != x) {
        update(1, 1, 2 * n, tin[x], tout[x], val);
      } else {
        long long a = lca(u, root);
        long long b = lca(v, root);
        long long next;
        if (a == x)
          next = b;
        else
          next = a;
        update(1, 1, 2 * n, 1, 2 * n, val);
        if (next != root) {
          long long tru = get_par(root, h[root] - h[next] - 1);
          update(1, 1, 2 * n, tin[tru], tout[tru], -val);
        }
      }
    } else {
      long long v;
      cin >> v;
      long long ans = 0;
      if (lca(root, v) != v) {
        ans = get_sum(1, 1, 2 * n, tin[v], tout[v]);
      } else {
        if (root == v)
          ans = st[1];
        else {
          ans = st[1];
          long long tru = get_par(root, h[root] - h[v] - 1);
          ans -= get_sum(1, 1, 2 * n, tin[tru], tout[tru]);
        }
      }
      ans /= 2;
      cout << ans << '\n';
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  solve();
}
