func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 100000 + 77, L = 17;   int n, q, tim = 1, root = 1;   int b[N], d[N], Par[N][L], St[N], En[N];   long long S[N << 2], lz[N << 2];   inline void Shift(int l, int r, int id) {     long long x = lz[id];     lz[id] = 0;     S[id] += (r - l) * x;     if (r - l > 1) lz[id << 1] += x, lz[id << 1 ^ 1] += x;   }   void Add(int ql, int qr, int x, int l = 1, int r = n + 1, int id = 1) {     Shift(l, r, id);     if (qr <= l || r <= ql) return;     if (ql <= l && r <= qr) {       lz[id] += x;       Shift(l, r, id);       return;     }     int mid = ((l + r) >> 1);     Add(ql, qr, x, l, mid, id << 1);     Add(ql, qr, x, mid, r, id << 1 ^ 1);     S[id] = S[id << 1] + S[id << 1 ^ 1];   }   long long Get(int ql, int qr, int l = 1, int r = n + 1, int id = 1) {     Shift(l, r, id);     if (qr <= l || r <= ql) return 0;     if (ql <= l && r <= qr) return S[id];     int mid = ((l + r) >> 1);     return Get(ql, qr, l, mid, id << 1) + Get(ql, qr, mid, r, id << 1 ^ 1);   }   vector<int> a[N];   void dfs(int v = 1) {     St[v] = tim++;     for (int i = 1; i < L; ++i) Par[v][i] = Par[Par[v][i - 1]][i - 1];     for (int u : a[v]) {       if (u == Par[v][0]) continue;       Par[u][0] = v;       d[u] = d[v] + 1;       dfs(u);     }     En[v] = tim;   }   inline bool isPar(int v, int u) { return St[v] <= St[u] && En[u] <= En[v]; }   inline int GetPar(int v, int k) {     for (int i = 0; i < L; ++i)       if (k & (1 << i)) v = Par[v][i];     return v;   }   inline int GetLca(int v, int u) {     if (d[v] < d[u]) swap(v, u);     v = GetPar(v, d[v] - d[u]);     if (v == u) return v;     for (int i = L - 1; i >= 0; --i)       if (Par[v][i] != Par[u][i]) v = Par[v][i], u = Par[u][i];     return Par[v][0];   }   inline int GetLca(int r, int v, int u) {     int t = GetLca(v, u);     if (isPar(r, t)) return t;     if (isPar(r, u) || isPar(r, v)) return r;     if (!isPar(t, r)) return t;     int x = GetLca(r, v);     int y = GetLca(r, u);     return (d[x] > d[y] ? x : y);   }   inline void Update(int r, int v, int u, int x) {     int t = GetLca(r, v, u);     if ((!isPar(t, r))) {       Add(St[t], En[t], x);       return;     }     Add(1, n + 1, x);     if (r == t) return;     int p = GetPar(r, d[r] - d[t] - 1);     Add(St[p], En[p], -x);   }   inline long long GetSum(int r, int v) {     if (!isPar(v, r)) return Get(St[v], En[v]);     long long res = Get(1, n + 1);     if (r == v) return res;     int p = GetPar(r, d[r] - d[v] - 1);     res -= Get(St[p], En[p]);     return res;   }   int main() {     scanf( %d %d , &n, &q);     for (int i = 1; i <= n; ++i) scanf( %d , b + i);     for (int v, u, i = 1; i < n; ++i)       scanf( %d %d , &v, &u), a[v].push_back(u), a[u].push_back(v);     d[1] = 1;     dfs();     for (int i = 1; i <= n; ++i) Add(St[i], St[i] + 1, b[i]);     while (q--) {       int tp, v, u, x;       scanf( %d %d , &tp, &v);       if (tp == 1) {         root = v;       } else if (tp == 2) {         scanf( %d %d , &u, &x);         Update(root, v, u, x);       } else {         printf( %lld n , GetSum(root, v));       }     }     return 0;   }   