#include <bits/stdc++.h>
using namespace std;
long n, q;
long long c[100001], it[4 * 100001], lazy[4 * 100001];
vector<long> a[100001];
long cha[20][100001], h[100001], in[100001], out[100001], cnt;
vector<int> d;
void nhap() {
  cin >> n >> q;
  for (long i = 1; i <= n; ++i) {
    cin >> c[i];
  }
  long u, v;
  for (long i = 1; i < n; ++i) {
    cin >> u >> v;
    a[u].push_back(v);
    a[v].push_back(u);
  }
}
void update(long k, long l, long r, long u, long v, long long val) {
  if (l > v || r < u) return;
  if (l >= u && r <= v) {
    it[k] += val * (r - l + 1);
    lazy[k] += val;
    return;
  }
  long mid = (l + r) / 2;
  if (lazy[k]) {
    update(k * 2, l, mid, l, r, lazy[k]);
    update(k * 2 + 1, mid + 1, r, l, r, lazy[k]);
    lazy[k] = false;
  }
  update(2 * k, l, mid, u, v, val);
  update(2 * k + 1, mid + 1, r, u, v, val);
  it[k] = it[2 * k] + it[2 * k + 1];
}
long long get(long k, long l, long r, long u, long v) {
  if (l > v || r < u) return 0;
  if (l >= u && r <= v) return it[k];
  long mid = (l + r) / 2;
  if (lazy[k]) {
    update(k * 2, l, mid, l, r, lazy[k]);
    update(k * 2 + 1, mid + 1, r, l, r, lazy[k]);
    lazy[k] = false;
  }
  return get(2 * k, l, mid, u, v) + get(2 * k + 1, mid + 1, r, u, v);
}
void dfs(long u) {
  in[u] = ++cnt;
  d.push_back(u);
  for (long i = 0; i < a[u].size(); ++i) {
    long v = a[u][i];
    if (v != cha[0][u]) {
      cha[0][v] = u;
      h[v] = h[u] + 1;
      dfs(v);
    }
  }
  out[u] = cnt;
}
void rmq() {
  for (long i = 1; i <= 19; ++i)
    for (long j = 1; j <= n; ++j) cha[i][j] = cha[i - 1][cha[i - 1][j]];
}
long lca(long u, long v) {
  if (h[u] < h[v]) swap(u, v);
  long denta = h[u] - h[v];
  for (long i = 19; i >= 0; --i)
    if ((denta >> i) & 1) u = cha[i][u];
  if (u == v) return u;
  for (long i = 19; i >= 0; --i)
    if (cha[i][v] != cha[i][u]) {
      u = cha[i][u];
      v = cha[i][v];
    }
  return cha[0][u];
}
void lam() {
  long type, u, v, x, pos2, pos1, pos3, root = 1;
  long long ans = 0;
  for (long i = 1; i <= q; ++i) {
    cin >> type;
    if (type == 1) cin >> root;
    if (type == 2) {
      cin >> u >> v >> x;
      pos1 = lca(u, v);
      pos2 = lca(root, u);
      pos3 = lca(root, v);
      if (pos1 != pos2 && pos1 != pos3) {
        update(1, 1, n, in[pos1], out[pos1], x);
      } else {
        update(1, 1, n, 1, n, x);
        long res = pos1 ^ pos2 ^ pos3, pos = root;
        if (pos == res) continue;
        long denta = h[pos] - h[res] - 1;
        for (long j = 19; j >= 0; --j)
          if ((denta >> j) & 1) pos = cha[j][pos];
        update(1, 1, n, in[pos], out[pos], -x);
      }
    }
    if (type == 3) {
      cin >> u;
      if (lca(u, root) != u)
        cout << get(1, 1, n, in[u], out[u]) << "\n";
      else {
        long pos = root;
        long denta = h[pos] - h[u] - 1;
        for (long j = 19; j >= 0; --j)
          if ((denta >> j) & 1) pos = cha[j][pos];
        cout << get(1, 1, n, 1, n) - get(1, 1, n, in[pos], out[pos]) << "\n";
      }
    }
  }
}
void kt(long k, long l, long r) {
  if (l == r) {
    it[k] = c[d[l - 1]];
    return;
  }
  long m = (l + r) / 2;
  kt(k * 2, l, m);
  kt(k * 2 + 1, m + 1, r);
  it[k] = it[k * 2] + it[k * 2 + 1];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  nhap();
  dfs(1);
  kt(1, 1, n);
  rmq();
  lam();
  return 0;
}
