#include <bits/stdc++.h>
const long long maxn = 1e5 + 5;
using namespace std;
vector<long long> adj[maxn];
long long n, q, root, cnt, cur, a[maxn];
long long st[maxn], en[maxn];
long long lazy[4 * maxn], sum[4 * maxn];
long long d[maxn], p[maxn][20], ver[maxn];
void init(long long i, long long l, long long r) {
  if (l == r) {
    sum[i] = a[ver[l]];
    return;
  }
  long long mid = (l + r) / 2;
  init(i * 2, l, mid);
  init(i * 2 + 1, mid + 1, r);
  sum[i] = sum[i * 2] + sum[i * 2 + 1];
}
void dolazy(long long i, long long l, long long r) {
  if (lazy[i] == 0) return;
  sum[i] += (r - l + 1) * lazy[i];
  if (l != r) {
    lazy[i * 2] += lazy[i];
    lazy[i * 2 + 1] += lazy[i];
  }
  lazy[i] = 0;
  return;
}
void update(long long i, long long l, long long r, long long L, long long R,
            long long val) {
  dolazy(i, l, r);
  if (L > r || l > R) return;
  if (L <= l && r <= R) {
    lazy[i] = val;
    dolazy(i, l, r);
    return;
  }
  long long mid = (l + r) / 2;
  update(i * 2, l, mid, L, R, val);
  update(i * 2 + 1, mid + 1, r, L, R, val);
  sum[i] = sum[i * 2] + sum[i * 2 + 1];
}
long long get(long long i, long long l, long long r, long long L, long long R) {
  dolazy(i, l, r);
  if (L > r || l > R) return 0;
  if (L <= l && r <= R) return sum[i];
  long long mid = (l + r) / 2;
  return get(i * 2, l, mid, L, R) + get(i * 2 + 1, mid + 1, r, L, R);
}
void dfs(long long u) {
  st[u] = ++cnt;
  ver[cnt] = u;
  for (long long i = 0; i < adj[u].size(); i++) {
    long long v = adj[u][i];
    if (v == p[u][0]) continue;
    d[v] = d[u] + 1;
    p[v][0] = u;
    dfs(v);
  }
  en[u] = cnt;
}
long long lca(long long u, long long v, long long curroot) {
  if (curroot == 1) {
    for (long long i = 17; i >= 0; i--)
      if (d[u] - (1 << i) >= d[v]) u = p[u][i];
    for (long long i = 17; i >= 0; i--)
      if (d[v] - (1 << i) >= d[u]) v = p[v][i];
    for (long long i = 17; i >= 0; i--)
      if (p[u][i] != p[v][i]) u = p[u][i], v = p[v][i];
    if (u != v) u = p[u][0];
    return u;
  }
  long long x = lca(u, v, 1), y = lca(u, curroot, 1), z = lca(v, curroot, 1);
  if (x == y) return z;
  if (x == z) return y;
  return x;
}
long long nxt(long long u, long long parent) {
  long long cur = d[parent] + 1;
  for (long long i = 17; i >= 0; i--)
    if (d[u] - (1 << i) >= cur) u = p[u][i];
  return u;
}
long long get(long long u) {
  if (u == root) return sum[1];
  if (lca(u, root, 1) != u) {
    return get(1, 1, n, st[u], en[u]);
  }
  long long v = nxt(root, u);
  return sum[1] - get(1, 1, n, st[v], en[v]);
}
void add(long long x, long long y, long long val) {
  long long u = lca(x, y, root);
  if (u == root) {
    lazy[1] = val;
    dolazy(1, 1, n);
    return;
  }
  if (lca(u, root, 1) != u) {
    update(1, 1, n, st[u], en[u], val);
    return;
  }
  long long v = nxt(root, u);
  lazy[1] = val;
  dolazy(1, 1, n);
  update(1, 1, n, st[v], en[v], -val);
}
void precal() {
  for (long long j = 1; j < 18; j++)
    for (long long i = 1; i <= n; i++) {
      p[i][j] = p[p[i][j - 1]][j - 1];
    }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> q;
  for (long long i = 1; i <= n; i++) cin >> a[i];
  for (long long i = 2; i <= n; i++) {
    long long u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  root = 1;
  dfs(1);
  precal();
  init(1, 1, n);
  while (q--) {
    long long type, u, v, x;
    cin >> type;
    if (type == 1) {
      cin >> v;
      root = v;
    }
    if (type == 2) {
      cin >> u >> v >> x;
      add(u, v, x);
    }
    if (type == 3) {
      cin >> v;
      cout << get(v) << "\n";
    }
  }
  return 0;
}
