#include <bits/stdc++.h>
using namespace std;
int64_t read() {
  bool b = 0;
  int64_t n = 0;
  char c = getchar();
  for (; !(('0') <= (c) && (c) <= ('9')); c = getchar()) b = (c == '-');
  for (; (('0') <= (c) && (c) <= ('9')); c = getchar()) n = 10 * n + (c - '0');
  if (b) n = -n;
  return n;
}
const int64_t N = 1e5 + 10;
int64_t _log[2 * N], ss[2 * N][20], bl[N][20];
vector<int64_t> adj[N];
int64_t h[N], first[N];
vector<int64_t> et;
int64_t V[N];
int64_t n, q;
int64_t tin[N], tout[N], t = -1;
int64_t stlen, sth;
int64_t lp[N];
int64_t st[2 * N];
void calc(int64_t i, int64_t k) {
  st[i] = st[i << 1] + st[i << 1 | 1] + lp[i] * k;
}
void app(int64_t i, int64_t vv, int64_t k) {
  st[i] += vv * k;
  if (i < stlen) lp[i] += vv;
}
void build(int64_t l, int64_t r) {
  int64_t k = 2;
  for (l += stlen, r += stlen - 1; l > 1; k <<= 1) {
    l >>= 1, r >>= 1;
    for (int64_t i = r; i >= l; --i) calc(i, k);
  }
}
void push(int64_t l, int64_t r) {
  int64_t s = sth, k = 1 << (sth - 1);
  for (l += stlen, r += stlen - 1; s > 0; --s, k >>= 1)
    for (int64_t i = l >> s; i <= r >> s; ++i)
      if (lp[i] != 0) {
        app(i << 1, lp[i], k);
        app(i << 1 | 1, lp[i], k);
        lp[i] = 0;
      }
}
void add(int64_t l, int64_t r, int64_t vv) {
  push(l, l + 1), push(r - 1, r);
  int64_t l0 = l, r0 = r, k = 1;
  for (l += stlen, r += stlen; l < r; l >>= 1, r >>= 1, k <<= 1) {
    if (l & 1) app(l++, vv, k);
    if (r & 1) app(--r, vv, k);
  }
  build(l0, l0 + 1), build(r0 - 1, r0);
}
int64_t query(int64_t l, int64_t r) {
  int64_t l0 = l, r0 = r;
  push(l, l + 1), push(r - 1, r);
  int64_t res = 0;
  for (l += stlen, r += stlen; l < r; l >>= 1, r >>= 1) {
    if (l & 1) res += st[l++];
    if (r & 1) res += st[--r];
  }
  l = l0, r = r0;
  return res;
}
void _clog() {
  for (int64_t i = 2; i < 2 * N; ++i) _log[i] = _log[i >> 1] + 1;
}
void clca() {
  int64_t n = et.size();
  for (int64_t i = 0; (i) < (n); ++(i)) ss[i][0] = et[i];
  for (int64_t k = 1; (1 << k) <= n; ++k)
    for (int64_t i = 0; i + (1 << k) <= n; ++i) {
      int64_t j = i + (1 << (k - 1));
      if (h[ss[i][k - 1]] < h[ss[j][k - 1]])
        ss[i][k] = ss[i][k - 1];
      else
        ss[i][k] = ss[j][k - 1];
    }
}
int64_t lca(int64_t l, int64_t r) {
  l = first[l], r = first[r];
  if (r < l) swap(l, r);
  int64_t k = _log[r - l + 1];
  int64_t a = ss[l][k], b = ss[r - (1 << k) + 1][k];
  if (h[a] < h[b])
    return a;
  else
    return b;
}
void pdfs(int64_t v, int64_t p) {
  first[v] = int64_t((et).size());
  tin[v] = ++t;
  et.push_back(v);
  bl[v][0] = p;
  for (int64_t i = 0; (i) < (19); ++(i)) bl[v][i + 1] = bl[bl[v][i]][i];
  for (int64_t c : adj[v]) {
    if (c == p) continue;
    h[c] = h[v] + 1;
    pdfs(c, v);
    et.push_back(v);
  }
  tout[v] = t;
}
int64_t rlca(int64_t root, int64_t l, int64_t r) {
  return lca(l, root) ^ lca(r, root) ^ lca(l, r);
}
int64_t up(int64_t v, int64_t first) {
  for (int64_t i = 19; first && i >= 0; --i)
    if ((1 << i) <= first) v = bl[v][i], first -= (1 << i);
  return v;
}
int64_t qsub(int64_t v) { return query(tin[v], tout[v] + 1); }
void msub(int64_t v, int64_t vv) { add(tin[v], tout[v] + 1, vv); }
int main() {
  ;
  n = read(), q = read(), stlen = n;
  sth = 8 * 4 - __builtin_clz(stlen);
  ;
  for (int64_t i = 0; (i) < (n); ++(i)) V[i] = read();
  int64_t a, b;
  for (int64_t i = 0; (i) < (n - 1); ++(i)) {
    a = read() - 1, b = read() - 1;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  _log[1] = 0;
  _clog();
  pdfs(0, 0);
  clca();
  ;
  for (int64_t i = 0; (i) < (n); ++(i))
    ;
  ;
  ;
  ;
  for (int64_t i = 0; (i) < (n); ++(i))
    ;
  ;
  ;
  for (int64_t i = 0; (i) < (n); ++(i)) st[stlen + tin[i]] = V[i];
  build(0, n);
  int64_t op, root = 0;
  while (q--) {
    op = read();
    if (op == 1) {
      root = read() - 1;
    } else if (op == 2) {
      int64_t v = rlca(root, read() - 1, read() - 1);
      int64_t vv = read();
      if (root == v) {
        msub(0, vv);
      } else if (lca(v, root) == v) {
        ;
        msub(0, vv), msub(up(root, h[root] - h[v] - 1), -vv);
      } else {
        msub(v, vv);
      }
    } else {
      int64_t v = read() - 1;
      ;
      assert(op == 3);
      if (root == v) {
        printf("%lld\n", qsub(0));
      } else if (lca(v, root) == v) {
        ;
        ;
        printf("%lld\n", qsub(0) - qsub(up(root, h[root] - h[v] - 1)));
      } else {
        printf("%lld\n", qsub(v));
      }
    };
    for (int64_t i = 0; (i) < (n); ++(i))
      ;
    ;
    ;
  }
  return 0;
}
