#include <bits/stdc++.h>
long long n, q, a[300000][2], c[200000], f[200000][21], de[200000], l[200000],
    r[200000], kk, kkk, cc, x, y, z, ff[200000], lazy[200000 << 2],
    sum[200000 << 2], last[200000], dd;
inline long long read() {
  char c = getchar();
  while (c != '-' && (c > '9' || c < '0')) c = getchar();
  long long k = 0, kk = 1;
  if (c == '-') kk = -1, c = getchar();
  while (c >= '0' && c <= '9') k = k * 10 + c - '0', c = getchar();
  return k * kk;
}
using namespace std;
void write(long long x) {
  if (x < 0) x = -x, putchar('-');
  if (x / 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
void dfs(long long x, long long fa, long long d) {
  f[x][0] = fa;
  de[x] = d;
  l[x] = ++kkk;
  ff[kkk] = x;
  for (long long i = last[x]; i; i = a[i][0])
    if (a[i][1] != fa) dfs(a[i][1], x, d + 1);
  r[x] = kkk;
}
long long lca(long long x, long long y) {
  if (de[x] < de[y]) swap(x, y);
  for (long long i = 20; i >= 0; i--)
    if (de[f[x][i]] >= de[y]) x = f[x][i];
  for (long long i = 20; i >= 0; i--)
    if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
  return x != y ? f[x][0] : x;
}
long long find(long long x, long long y, long long z) {
  long long xx = lca(x, y), yy = lca(y, z), zz = lca(x, z);
  if (lca(xx, z) != xx) return xx;
  if (de[yy] > de[zz])
    return yy;
  else
    return zz;
}
long long calc(long long x, long long y) {
  for (long long i = 20; i >= 0; i--)
    if (de[f[x][i]] > de[y]) x = f[x][i];
  return x;
}
void pushdown(long long d, long long l, long long r) {
  long long m = (l + r) / 2;
  lazy[d * 2] += lazy[d];
  lazy[d * 2 + 1] += lazy[d];
  sum[d * 2] += lazy[d] * (m - l + 1);
  sum[d * 2 + 1] += lazy[d] * (r - m);
  lazy[d] = 0;
}
void build(long long l, long long r, long long d) {
  if (l == r) {
    sum[d] = c[ff[l]];
    return;
  }
  long long m = (l + r) / 2;
  build(l, m, d * 2);
  build(m + 1, r, d * 2 + 1);
  sum[d] = sum[d * 2] + sum[d * 2 + 1];
}
void putit(long long x, long long y, long long z, long long l, long long r,
           long long d) {
  if (x > y) return;
  if (x <= l && y >= r) {
    lazy[d] += z;
    sum[d] += z * (r - l + 1);
    return;
  }
  if (lazy[d]) pushdown(d, l, r);
  long long m = (l + r) / 2;
  if (x <= m) putit(x, y, z, l, m, d * 2);
  if (y > m) putit(x, y, z, m + 1, r, d * 2 + 1);
  sum[d] = sum[d * 2] + sum[d * 2 + 1];
}
long long findit(long long x, long long y, long long l, long long r,
                 long long d) {
  if (x > y) return 0;
  if (x <= l && y >= r) return sum[d];
  if (lazy[d]) pushdown(d, l, r);
  long long m = (l + r) / 2, ans = 0;
  if (x <= m) ans += findit(x, y, l, m, d * 2);
  if (y > m) ans += findit(x, y, m + 1, r, d * 2 + 1);
  return ans;
}
void doit(long long x, long long y) {
  a[++kk][0] = last[x];
  a[kk][1] = y;
  last[x] = kk;
}
signed main() {
  n = read();
  q = read();
  for (long long i = 1; i <= n; i++) c[i] = read();
  for (long long i = 1; i < n; i++)
    x = read(), y = read(), doit(x, y), doit(y, x);
  dfs(1, 0, 1);
  dd = 1;
  build(1, n, 1);
  for (long long j = 1; j <= 20; j++)
    for (long long i = 1; i <= n; i++) f[i][j] = f[f[i][j - 1]][j - 1];
  while (q--) {
    cc = read();
    if (cc == 1)
      dd = read();
    else if (cc == 2) {
      x = read();
      y = read();
      z = read();
      long long k = find(x, y, dd);
      if (k == dd)
        putit(1, n, z, 1, n, 1);
      else if (lca(dd, k) == k)
        kk = calc(dd, k), putit(1, l[kk] - 1, z, 1, n, 1),
        putit(r[kk] + 1, n, z, 1, n, 1);
      else
        putit(l[k], r[k], z, 1, n, 1);
    } else {
      x = read();
      if (x == dd)
        writeln(findit(1, n, 1, n, 1));
      else if (lca(x, dd) == x)
        x = calc(dd, x),
        writeln(findit(1, l[x] - 1, 1, n, 1) + findit(r[x] + 1, n, 1, n, 1));
      else
        writeln(findit(l[x], r[x], 1, n, 1));
    }
  }
}
