func_code_string: #include <bits/stdc++.h>   const int S = 200003;   int n, m, h[S], nx[S], v[S], eg = 1, s[S], e[S], _ = 0, t[S], fa[S], dep[S],                                f[S], rk[S], root, a[S];   inline void egadd(int uu, int vv) {     nx[++eg] = h[uu];     h[uu] = eg;     v[eg] = vv;   }   void dfs_1(int x) {     s[x] = 1;     for (int i = h[x]; i; i = nx[i])       if (v[i] != fa[x]) {         fa[v[i]] = x;         dep[v[i]] = dep[x] + 1;         dfs_1(v[i]);         s[x] += s[v[i]];         if (s[e[x]] < s[v[i]]) e[x] = v[i];       }   }   void dfs_2(int x, int top) {     f[x] = ++_;     rk[_] = x;     t[x] = top;     if (!e[x]) return;     dfs_2(e[x], top);     for (int i = h[x]; i; i = nx[i])       if (v[i] != fa[x] && v[i] != e[x]) dfs_2(v[i], v[i]);   }   long long sg[S << 2], add[S << 2];   inline void down(int w, int l, int r) {     if (add[w]) {       int mid = (l + r) >> 1;       add[(w << 1)] += add[w];       add[(w << 1) | 1] += add[w];       sg[(w << 1)] += add[w] * (mid - l + 1);       sg[(w << 1) | 1] += add[w] * (r - mid);       add[w] = 0;     }   }   inline void sgadd(int l, int r, int ll, int rr, int k, int w) {     if (ll <= l && r <= rr) {       sg[w] += 1ll * (r - l + 1) * k;       add[w] += k;       return;     }     int mid = (l + r) >> 1;     down(w, l, r);     if (ll <= mid) sgadd(l, mid, ll, rr, k, (w << 1));     if (rr > mid) sgadd(mid + 1, r, ll, rr, k, (w << 1) | 1);     sg[w] = sg[(w << 1)] + sg[(w << 1) | 1];   }   inline void sgb(int l, int r, int w) {     if (l == r) {       sg[w] = a[rk[l]];       return;     }     int mid = (l + r) >> 1;     sgb(l, mid, (w << 1));     sgb(mid + 1, r, (w << 1) | 1);     sg[w] = sg[(w << 1)] + sg[(w << 1) | 1];   }   inline long long sgcal(int l, int r, int ll, int rr, int w) {     if (ll <= l && r <= rr) return sg[w];     int mid = (l + r) >> 1;     down(w, l, r);     long long ret = 0;     if (ll <= mid) ret += sgcal(l, mid, ll, rr, (w << 1));     if (rr > mid) ret += sgcal(mid + 1, r, ll, rr, (w << 1) | 1);     return ret;   }   inline int hang(int x, int y) {     while (true) {       if (fa[t[y]] == x) return t[y];       if (f[t[y]] <= f[x] && f[x] <= f[y]) return e[x];       y = fa[t[y]];     }   }   inline int lca(int x, int y) {     while (t[x] != t[y]) {       if (dep[t[x]] < dep[t[y]]) x ^= y ^= x ^= y;       x = fa[t[x]];     }     if (x == y) return x;     if (dep[x] > dep[y])       return y;     else       return x;   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 1; i <= n; i++) scanf( %d , a + i);     for (int i = 1; i < n; i++) {       int uu, vv;       scanf( %d%d , &uu, &vv);       egadd(uu, vv);       egadd(vv, uu);     }     root = 1;     dfs_1(1);     dfs_2(1, 1);     sgb(1, n, 1);     int o, x, y, z;     while (m--) {       scanf( %d%d , &o, &x);       if (o == 1)         root = x;       else if (o == 2) {         scanf( %d%d , &y, &z);         int o1, o2, o3;         o1 = lca(x, y);         if (o1 != root && (f[o1] <= f[root] && f[root] <= f[o1] + s[o1] - 1)) {           o2 = lca(x, root);           o3 = lca(y, root);           if (dep[o1] < dep[o2]) o1 = o2;           if (dep[o1] < dep[o3]) o1 = o3;           if (o1 == root)             sgadd(1, n, 1, n, z, 1);           else {             o2 = hang(o1, root);             sgadd(1, n, 1, n, z, 1);             sgadd(1, n, f[o2], f[o2] + s[o2] - 1, -z, 1);           }         } else if (o1 == root)           sgadd(1, n, 1, n, z, 1);         else           sgadd(1, n, f[o1], f[o1] + s[o1] - 1, z, 1);       } else {         if (x != root && (f[x] <= f[root] && f[root] <= f[x] + s[x] - 1)) {           int o = hang(x, root);           printf( %lld n ,                  sgcal(1, n, 1, n, 1) - sgcal(1, n, f[o], f[o] + s[o] - 1, 1));         } else if (x == root)           printf( %lld n , sgcal(1, n, 1, n, 1));         else           printf( %lld n , sgcal(1, n, f[x], f[x] + s[x] - 1, 1));       }     }     return 0;   }   