func_code_string: #include <bits/stdc++.h>   using namespace std;   const long long N = 1e5 + 30, Mod = 1e9 + 7;   const long long SQ = 330;   const long long LOG = 20;   long long n, q, Par[LOG][N], a[N], H[N], St[N], Fn[N], Lazy[N << 2], T, Fen[N],       Seg[N << 2], root = 1;   vector<long long> G[N];   void DFS(long long v = 1, long long par = 0) {     St[v] = T++;     Par[0][v] = par;     for (int i = 1; i < LOG; i++) Par[i][v] = Par[i - 1][Par[i - 1][v]];     for (auto u : G[v]) {       if (u == par) continue;       H[u] = H[v] + 1;       DFS(u, v);     }     Fn[v] = T;   }   void Shift(int id, int b, int e) {     long long val = Lazy[id];     Seg[(id << 1)] += (((b + e) >> 1) - b) * val;     Seg[((id << 1) | 1)] += (e - ((b + e) >> 1)) * val;     Lazy[(id << 1)] += val;     Lazy[((id << 1) | 1)] += val;     Lazy[id] = 0;   }   void Add(int l, int r, long long val = 0, int id = 1, int b = 0, int e = n) {     if (r <= b || e <= l) return;     if (l <= b && e <= r) {       Seg[id] += val * (e - b);       Lazy[id] += val;       return;     }     Shift(id, b, e);     Add(l, r, val, (id << 1), b, ((b + e) >> 1));     Add(l, r, val, ((id << 1) | 1), ((b + e) >> 1), e);     Seg[id] = Seg[(id << 1)] + Seg[((id << 1) | 1)];   }   long long Get(int l, int r, int id = 1, int b = 0, int e = n) {     if (r <= b || e <= l) return 0;     if (l <= b && e <= r) return Seg[id];     Shift(id, b, e);     return Get(l, r, (id << 1), b, ((b + e) >> 1)) +            Get(l, r, ((id << 1) | 1), ((b + e) >> 1), e);   }   bool is_par(long long v, long long u) {     return St[v] <= St[u] && Fn[u] <= Fn[v];   }   long long Up(long long v, long long h) {     for (int i = LOG - 1; ~i; i--)       if (h & (1 << i)) v = Par[i][v];     return v;   }   long long LLCA(long long v, long long u) {     if (H[v] < H[u]) swap(v, u);     v = Up(v, H[v] - H[u]);     if (v == u) return v;     for (int i = LOG - 1; ~i; i--) {       if (Par[i][v] ^ Par[i][u]) {         v = Par[i][v];         u = Par[i][u];       }     }     return Par[0][v];   }   long long LCA(long long v, long long u) {     if (is_par(root, v) && is_par(root, u)) return LLCA(v, u);     if (is_par(root, v) && !is_par(root, u)) return root;     if (is_par(root, u) && !is_par(root, v)) return root;     long long l = LLCA(v, u);     if (is_par(v, u)) {       long long x = LLCA(u, root);       if (is_par(v, x)) return x;       return v;     }     if (is_par(u, v)) {       long long x = LLCA(v, root);       if (is_par(u, x)) return x;       return u;     }     if (is_par(l, root)) {       long long f = LLCA(v, root);       long long f2 = LLCA(u, root);       if (H[f2] > H[f]) {         return f2;       }       return f;     }     return l;   }   void Inp() {     cin >> n >> q;     for (int i = 1; i <= n; i++) {       cin >> a[i];     }     for (int i = 0; i < n - 1; i++) {       long long v, u;       cin >> v >> u;       G[v].push_back(u);       G[u].push_back(v);     }     DFS(1, 0);     for (int i = 1; i <= n; i++) {       Add(St[i], St[i] + 1, a[i]);     }   }   void Add_Sub(long long v, long long val) {     if (v == root) {       Add(0, n, val);       return;     }     if (is_par(root, v)) {       Add(St[v], Fn[v], val);       return;     }     if (is_par(v, root)) {       long long dif = H[root] - H[v] - 1;       long long rr = Up(root, dif);       Add(0, n, val);       Add(St[rr], Fn[rr], -val);       return;     }     Add(St[v], Fn[v], val);   }   long long Get_Sub(long long v) {     if (v == root) return Get(0, n);     if (is_par(root, v)) {       return Get(St[v], Fn[v]);     }     if (is_par(v, root)) {       long long dif = H[root] - H[v] - 1;       long long rr = Up(root, dif);       return Get(0, n) - Get(St[rr], Fn[rr]);     }     return Get(St[v], Fn[v]);   }   int main() {     ios::sync_with_stdio(0), cin.tie(0);     Inp();     while (q--) {       long long t;       cin >> t;       if (t == 1) {         long long v;         cin >> v;         root = v;       }       if (t == 2) {         long long v, u, x;         cin >> v >> u >> x;         long long l = LCA(v, u);         Add_Sub(l, x);       }       if (t == 3) {         long long v;         cin >> v;         cout << Get_Sub(v) <<   n ;       }     }   }   