#include <bits/stdc++.h>
using namespace std;
struct Node {
  long long lazy, val;
};
Node tree[4 * 100010];
void update_node(int idx, int b, int e, long long v) {
  tree[idx].val += ((e - b + 1) * v);
  tree[idx].lazy += v;
}
void lazy_update(int idx, int b, int e) {
  if (tree[idx].lazy != 0) {
    update_node((idx << 1), b, (b + e) >> 1, tree[idx].lazy);
    update_node(((idx << 1) + 1), ((b + e) >> 1) + 1, e, tree[idx].lazy);
    tree[idx].lazy = 0;
  }
}
long long query(int idx, int b, int e, int st, int en) {
  if (st > e || en < b) return 0;
  if (st <= b && en >= e) return tree[idx].val;
  lazy_update(idx, b, e);
  long long lft = query((idx << 1), b, (b + e) >> 1, st, en);
  long long rgt = query(((idx << 1) + 1), ((b + e) >> 1) + 1, e, st, en);
  return lft + rgt;
}
void update(int idx, int b, int e, int st, int en, int v) {
  if (st > e || en < b) return;
  if (st <= b && en >= e) {
    update_node(idx, b, e, v);
    return;
  }
  lazy_update(idx, b, e);
  update((idx << 1), b, (b + e) >> 1, st, en, v);
  update(((idx << 1) + 1), ((b + e) >> 1) + 1, e, st, en, v);
  tree[idx].val = tree[(idx << 1)].val + tree[((idx << 1) + 1)].val;
}
vector<int> mat[100010];
int pa[100010][20], lev[100010], mota[100010], root, bam[100010], daan[100010],
    tim;
int dfs(int p, int pap) {
  mota[p] = 1;
  bam[p] = ++tim;
  for (int i = 0; i <= (int)mat[p].size() - 1; i++) {
    int x = mat[p][i];
    if (x != pap) {
      lev[x] = lev[p] + 1;
      pa[x][0] = p;
      mota[p] += dfs(x, p);
    }
  }
  daan[p] = tim;
  return mota[p];
}
void sparce_table(int n) {
  for (int l = 1; l <= 19; l++)
    for (int i = 1; i <= n; i++) {
      int lp = pa[i][l - 1], cp = -1;
      if (lp != -1) cp = pa[lp][l - 1];
      pa[i][l] = cp;
    }
  return;
}
int make_same(int niche, int upore, int bs) {
  if (lev[niche] == lev[upore]) return niche;
  int x = pa[niche][bs];
  if (x == -1 || lev[x] < lev[upore])
    return make_same(niche, upore, bs - 1);
  else
    return make_same(x, upore, bs);
}
int lca(int f, int s, int bs) {
  if (f == s) return f;
  if (pa[f][0] == pa[s][0]) return pa[f][0];
  int x = pa[f][bs], y = pa[s][bs];
  if (x == y)
    return lca(f, s, bs - 1);
  else
    return lca(x, y, bs);
}
int find_lca(int f, int s) {
  if (lev[f] > lev[s])
    f = make_same(f, s, 19);
  else
    s = make_same(s, f, 19);
  return lca(f, s, 19);
}
int jao(int chi, int V, int bs) {
  if (bs == -1) return bs;
  if (lev[chi] == V) return chi;
  int x = pa[chi][bs];
  if (x == -1 || lev[x] < V)
    return jao(chi, V, bs - 1);
  else
    return jao(x, V, bs);
}
int isPa(int chi, int bap) {
  if (lev[bap] > lev[chi]) return 0;
  int x = jao(chi, lev[bap], 19);
  if (x == bap)
    return 1;
  else
    return 0;
}
int ar[100010];
void doUp(int n) {
  root = 1;
  lev[1] = 1;
  pa[1][0] = -1;
  dfs(1, 1);
  sparce_table(n);
  for (int i = 1; i <= n; i++) update(1, 1, 100010, bam[i], bam[i], ar[i]);
  return;
}
int main() {
  ios::sync_with_stdio(false);
  int n, a, b, v, q, x, u, ty, c, d;
  cin >> n >> q;
  for (int i = 1; i <= n; i++) cin >> ar[i];
  for (int i = 1; i <= n - 1; i++) {
    cin >> a >> b;
    mat[a].push_back(b);
    mat[b].push_back(a);
  }
  doUp(n);
  for (int i = 1; i <= q; i++) {
    cin >> ty;
    if (ty == 1)
      cin >> root;
    else if (ty == 2) {
      cin >> u >> v >> x;
      a = isPa(u, root);
      b = isPa(v, root);
      if (a & b) {
        int c = find_lca(u, v);
        if (c == root)
          update(1, 1, 100010, bam[1], daan[1], x);
        else
          update(1, 1, 100010, bam[c], daan[c], x);
      } else if (a || b) {
        update(1, 1, 100010, bam[1], daan[1], x);
      } else {
        a = find_lca(u, v);
        d = a;
        a = find_lca(u, root);
        if (lev[a] > lev[d]) d = a;
        a = find_lca(v, root);
        if (lev[a] > lev[d]) d = a;
        if (isPa(root, d)) {
          update(1, 1, 100010, bam[1], daan[1], x);
          a = jao(root, lev[d] + 1, 19);
          update(1, 1, 100010, bam[a], daan[a], x * -1);
        } else
          update(1, 1, 100010, bam[d], daan[d], x);
      }
    } else if (ty == 3) {
      cin >> u;
      if (u == root) {
        cout << query(1, 1, 100010, bam[1], daan[1]) << endl;
      } else if (isPa(root, u)) {
        long long ret = query(1, 1, 100010, bam[1], daan[1]);
        a = jao(root, lev[u] + 1, 19);
        ret -= query(1, 1, 100010, bam[a], daan[a]);
        cout << ret << endl;
      } else {
        cout << query(1, 1, 100010, bam[u], daan[u]) << endl;
      }
    }
  }
  return 0;
}
