#include <bits/stdc++.h>
using namespace std;
const long long N = 1e5 + 5;
long long R = 1, n, q, arr[N];
vector<long long> a[N];
long long h[N], p[N][20];
long long cnt = 0, st[N], en[N], pos[2 * N];
long long it[8 * N], lz[8 * N];
void dfs(long long u) {
  st[u] = ++cnt;
  pos[cnt] = arr[u];
  for (long long i = 1; i < 17; ++i) p[u][i] = p[p[u][i - 1]][i - 1];
  for (long long i = 0; i < a[u].size(); ++i) {
    long long v = a[u][i];
    if (v == p[u][0]) continue;
    h[v] = h[u] + 1;
    p[v][0] = u;
    dfs(v);
  }
  en[u] = ++cnt;
  pos[cnt] = arr[u];
}
long long par(long long u, long long d) {
  for (long long i = 0; i < 17; ++i)
    if ((d >> i & 1)) u = p[u][i];
  return u;
}
long long lca(long long u, long long v) {
  if (h[u] != h[v]) {
    if (h[u] < h[v]) swap(u, v);
    u = par(u, h[u] - h[v]);
  }
  if (u == v) return u;
  for (long long i = 16; i >= 0; --i)
    if (p[u][i] != p[v][i]) {
      u = p[u][i];
      v = p[v][i];
    }
  return p[u][0];
}
void build_IT(long long i, long long l, long long r) {
  if (l == r) {
    it[i] = pos[l];
    return;
  }
  long long m = (l + r) / 2;
  build_IT(i * 2, l, m);
  build_IT(i * 2 + 1, m + 1, r);
  it[i] = it[i * 2] + it[i * 2 + 1];
}
void true_val(long long i, long long l, long long r) {
  if (lz[i] == 0) return;
  it[i] += (r - l + 1) * lz[i];
  if (l != r) {
    lz[i * 2] += lz[i];
    lz[i * 2 + 1] += lz[i];
  }
  lz[i] = 0;
}
void update(long long i, long long l, long long r, long long a, long long b,
            long long val) {
  true_val(i, l, r);
  if (l > b || r < a || l > r) return;
  if (a <= l && r <= b) {
    it[i] += (r - l + 1) * val;
    if (l != r) {
      lz[i * 2] += val;
      lz[i * 2 + 1] += val;
    }
    return;
  }
  long long m = (l + r) / 2;
  update(i * 2, l, m, a, b, val);
  update(i * 2 + 1, m + 1, r, a, b, val);
  it[i] = it[i * 2] + it[i * 2 + 1];
}
long long get(long long i, long long l, long long r, long long a, long long b) {
  true_val(i, l, r);
  if (l > b || r < a || l > r) return 0;
  if (a <= l && r <= b) return it[i];
  long long m = (l + r) / 2;
  return get(i * 2, l, m, a, b) + get(i * 2 + 1, m + 1, r, a, b);
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  scanf("%lld%lld", &n, &q);
  for (long long i = 1; i <= n; ++i) scanf("%lld", &arr[i]);
  for (long long i = 1; i < n; ++i) {
    long long x, y;
    scanf("%lld%lld", &x, &y);
    a[x].push_back(y);
    a[y].push_back(x);
  }
  dfs(1);
  n *= 2;
  build_IT(1, 1, n);
  while (q--) {
    long long t;
    scanf("%lld", &t);
    if (t == 1) {
      scanf("%lld", &R);
      continue;
    }
    if (t == 3) {
      long long u, ans = 0;
      scanf("%lld", &u);
      if (lca(R, u) != u)
        ans = get(1, 1, n, st[u], en[u]);
      else if (R == u)
        ans = it[1];
      else {
        long long z = par(R, h[R] - h[u] - 1);
        ans = it[1] - get(1, 1, n, st[z], en[z]);
      }
      printf("%lld\n", ans / 2);
      continue;
    }
    long long u, v, val;
    scanf("%lld%lld%lld", &u, &v, &val);
    long long x = lca(u, v);
    if (lca(x, R) != x)
      update(1, 1, n, st[x], en[x], val);
    else {
      long long a = lca(u, R), b = lca(v, R);
      long long w = (a == x ? b : a);
      update(1, 1, n, 1, n, val);
      if (w != R) {
        long long z = par(R, h[R] - h[w] - 1);
        update(1, 1, n, st[z], en[z], -val);
      }
    }
  }
}
