func_code_string: #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);         }       }     }   }   