#include <bits/stdc++.h>
using namespace std;
struct seg {
  long l, r;
};
long n, q, u, v, par[100005][20], dem = 0, type, root;
long tour[100005], check[100005], child[100005], h[100005];
long long a[100005], val;
seg sub[100005];
vector<long> adj[100005];
void build(int u) {
  dem++;
  tour[dem] = u;
  check[u] = child[u] = 1;
  for (int v : adj[u]) {
    if (check[v] == 0) {
      h[v] = h[u] + 1;
      build(v);
      par[v][0] = u;
      child[u] += child[v];
    }
  }
}
long lca(int u, int v) {
  if (h[u] < h[v]) swap(u, v);
  for (int i = 19; i >= 0; i--) {
    if (h[u] - (1 << i) >= h[v]) {
      u = par[u][i];
    }
  }
  if (u == v) {
    return u;
  } else {
    for (int i = 19; i >= 0; i--) {
      if (par[u][i] != par[v][i] && par[u][i] != -1 && par[v][i] != -1) {
        u = par[u][i];
        v = par[v][i];
      }
    }
    return par[u][0];
  }
}
long long st[500005], lazy[500005];
void update(long id, long l, long r, long i, long j, long long x) {
  if (lazy[id] != 0) {
    st[id] = st[id] + (r - l + 1) * lazy[id];
    if (l < r) {
      lazy[2 * id] += lazy[id];
      lazy[2 * id + 1] += lazy[id];
    }
    lazy[id] = 0;
  }
  if (l > j || r < i || i > j) {
    return;
  }
  if (l >= i && r <= j) {
    st[id] = st[id] + (r - l + 1) * x;
    if (l < r) {
      lazy[2 * id] = lazy[2 * id] + x;
      lazy[2 * id + 1] = lazy[2 * id + 1] + x;
    }
    return;
  }
  long mid = (l + r) / 2;
  update(2 * id, l, mid, i, j, x);
  update(2 * id + 1, mid + 1, r, i, j, x);
  st[id] = st[2 * id] + st[2 * id + 1];
}
long long get(long id, long l, long r, long i, long j) {
  if (lazy[id] != 0) {
    st[id] = st[id] + (r - l + 1) * lazy[id];
    if (l < r) {
      lazy[2 * id] += lazy[id];
      lazy[2 * id + 1] += lazy[id];
    }
    lazy[id] = 0;
  }
  if (l > j || r < i) {
    return 0;
  }
  if (l >= i && r <= j) {
    return st[id];
  }
  long mid = (l + r) / 2;
  return get(2 * id, l, mid, i, j) + get(2 * id + 1, mid + 1, r, i, j);
}
int main() {
  scanf("%ld %ld", &n, &q);
  memset(par, -1, sizeof par);
  for (int i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
    par[i][0] = i;
  }
  for (int i = 1; i < n; i++) {
    scanf("%ld %ld", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  build(1);
  for (int j = 1; (1 << j) < n; j++) {
    for (int i = 1; i <= n; i++) {
      if (par[i][j - 1] != -1) {
        par[i][j] = par[par[i][j - 1]][j - 1];
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    sub[tour[i]].l = i;
    sub[tour[i]].r = i + child[tour[i]] - 1;
    update(1, 1, n, i, i, a[tour[i]]);
  }
  root = 1;
  for (int vl = 1; vl <= q; vl++) {
    scanf("%ld", &type);
    if (type == 1) {
      scanf("%ld", &v);
      root = v;
    }
    if (type == 2) {
      scanf("%ld %ld %lld", &u, &v, &val);
      long lca_u = lca(root, u), lca_v = lca(root, v), lca_uv = lca(u, v);
      long ver, mx = -1;
      if (h[lca_u] > mx) {
        ver = lca_u;
        mx = h[lca_u];
      }
      if (h[lca_v] > mx) {
        ver = lca_v;
        mx = h[lca_v];
      }
      if (h[lca_uv] > mx) {
        ver = lca_uv;
        mx = h[lca_uv];
      }
      if (ver == root) {
        update(1, 1, n, sub[1].l, sub[1].r, val);
      } else {
        if (lca(ver, root) != ver) {
          update(1, 1, n, sub[ver].l, sub[ver].r, val);
        } else {
          update(1, 1, n, sub[1].l, sub[1].r, val);
          long pos = root;
          for (int i = 19; i >= 0; i--) {
            if (h[pos] - (1 << i) > h[ver]) {
              pos = par[pos][i];
            }
          }
          update(1, 1, n, sub[pos].l, sub[pos].r, -val);
        }
      }
    }
    if (type == 3) {
      scanf("%ld", &v);
      if (v == root) {
        printf("%lld\n", get(1, 1, n, 1, n));
      } else {
        if (lca(v, root) == root) {
          printf("%lld\n", get(1, 1, n, sub[v].l, sub[v].r));
        } else {
          if (lca(v, root) != v) {
            printf("%lld\n", get(1, 1, n, sub[v].l, sub[v].r));
          } else {
            long long ans = get(1, 1, n, 1, n);
            long pos = root;
            for (int i = 19; i >= 0; i--) {
              if (h[pos] - (1 << i) > h[v]) {
                pos = par[pos][i];
              }
            }
            long long tmp = get(1, 1, n, sub[pos].l, sub[pos].r);
            printf("%lld\n", ans - tmp);
          }
        }
      }
    }
  }
}
