#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 30, Mod = 1e9 + 7;
const long long SQ = 330;
const long long LOG = 20;
long long n, q, Par[LOG][N], a[N], H[N], St[N], Fn[N], Lazy[N << 2], T, Fen[N],
    Seg[N << 2], root = 1;
vector<long long> G[N];
void DFS(long long v = 1, long long par = 0) {
  St[v] = T++;
  Par[0][v] = par;
  for (int i = 1; i < LOG; i++) Par[i][v] = Par[i - 1][Par[i - 1][v]];
  for (auto u : G[v]) {
    if (u == par) continue;
    H[u] = H[v] + 1;
    DFS(u, v);
  }
  Fn[v] = T;
}
void Shift(int id, int b, int e) {
  long long val = Lazy[id];
  Seg[(id << 1)] += (((b + e) >> 1) - b) * val;
  Seg[((id << 1) | 1)] += (e - ((b + e) >> 1)) * val;
  Lazy[(id << 1)] += val;
  Lazy[((id << 1) | 1)] += val;
  Lazy[id] = 0;
}
void Add(int l, int r, long long val = 0, int id = 1, int b = 0, int e = n) {
  if (r <= b || e <= l) return;
  if (l <= b && e <= r) {
    Seg[id] += val * (e - b);
    Lazy[id] += val;
    return;
  }
  Shift(id, b, e);
  Add(l, r, val, (id << 1), b, ((b + e) >> 1));
  Add(l, r, val, ((id << 1) | 1), ((b + e) >> 1), e);
  Seg[id] = Seg[(id << 1)] + Seg[((id << 1) | 1)];
}
long long Get(int l, int r, int id = 1, int b = 0, int e = n) {
  if (r <= b || e <= l) return 0;
  if (l <= b && e <= r) return Seg[id];
  Shift(id, b, e);
  return Get(l, r, (id << 1), b, ((b + e) >> 1)) +
         Get(l, r, ((id << 1) | 1), ((b + e) >> 1), e);
}
bool is_par(long long v, long long u) {
  return St[v] <= St[u] && Fn[u] <= Fn[v];
}
long long Up(long long v, long long h) {
  for (int i = LOG - 1; ~i; i--)
    if (h & (1 << i)) v = Par[i][v];
  return v;
}
long long LLCA(long long v, long long u) {
  if (H[v] < H[u]) swap(v, u);
  v = Up(v, H[v] - H[u]);
  if (v == u) return v;
  for (int i = LOG - 1; ~i; i--) {
    if (Par[i][v] ^ Par[i][u]) {
      v = Par[i][v];
      u = Par[i][u];
    }
  }
  return Par[0][v];
}
long long LCA(long long v, long long u) {
  if (is_par(root, v) && is_par(root, u)) return LLCA(v, u);
  if (is_par(root, v) && !is_par(root, u)) return root;
  if (is_par(root, u) && !is_par(root, v)) return root;
  long long l = LLCA(v, u);
  if (is_par(v, u)) {
    long long x = LLCA(u, root);
    if (is_par(v, x)) return x;
    return v;
  }
  if (is_par(u, v)) {
    long long x = LLCA(v, root);
    if (is_par(u, x)) return x;
    return u;
  }
  if (is_par(l, root)) {
    long long f = LLCA(v, root);
    long long f2 = LLCA(u, root);
    if (H[f2] > H[f]) {
      return f2;
    }
    return f;
  }
  return l;
}
void Inp() {
  cin >> n >> q;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 0; i < n - 1; i++) {
    long long v, u;
    cin >> v >> u;
    G[v].push_back(u);
    G[u].push_back(v);
  }
  DFS(1, 0);
  for (int i = 1; i <= n; i++) {
    Add(St[i], St[i] + 1, a[i]);
  }
}
void Add_Sub(long long v, long long val) {
  if (v == root) {
    Add(0, n, val);
    return;
  }
  if (is_par(root, v)) {
    Add(St[v], Fn[v], val);
    return;
  }
  if (is_par(v, root)) {
    long long dif = H[root] - H[v] - 1;
    long long rr = Up(root, dif);
    Add(0, n, val);
    Add(St[rr], Fn[rr], -val);
    return;
  }
  Add(St[v], Fn[v], val);
}
long long Get_Sub(long long v) {
  if (v == root) return Get(0, n);
  if (is_par(root, v)) {
    return Get(St[v], Fn[v]);
  }
  if (is_par(v, root)) {
    long long dif = H[root] - H[v] - 1;
    long long rr = Up(root, dif);
    return Get(0, n) - Get(St[rr], Fn[rr]);
  }
  return Get(St[v], Fn[v]);
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  Inp();
  while (q--) {
    long long t;
    cin >> t;
    if (t == 1) {
      long long v;
      cin >> v;
      root = v;
    }
    if (t == 2) {
      long long v, u, x;
      cin >> v >> u >> x;
      long long l = LCA(v, u);
      Add_Sub(l, x);
    }
    if (t == 3) {
      long long v;
      cin >> v;
      cout << Get_Sub(v) << '\n';
    }
  }
}
