func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 1e5 + 5;   int n, m, rt;   int p[20][N], sz[N];   bool vis[N];   int dep[N], yr[N];   int cur = 1, pos[N], chainhd[N], chain[N], rpos[N];   int L[100 * N], R[100 * N], t[100 * N], root[N], nxt = 1, num;   int query[N], a[N], b[N], k[N], y[N];   vector<int> g[N];   void build(int id, int x, int y) {     if (x == y) {       return;     }     L[id] = nxt++;     R[id] = nxt++;     int mid = (x + y) >> 1;     build(L[id], x, mid);     build(R[id], mid + 1, y);   }   int update(int id, int x, int y, int l) {     if (l < x or l > y) return id;     int ID = nxt++;     if (x == y) {       t[ID] = t[id] + 1;       return ID;     }     int mid = (x + y) >> 1;     L[ID] = update(L[id], x, mid, l);     R[ID] = update(R[id], mid + 1, y, l);     t[ID] = t[L[ID]] + t[R[ID]];     return ID;   }   void dfs(int x) {     vis[x] = 1;     sz[x] = 1;     for (auto it : g[x]) {       if (!vis[it]) {         dep[it] = dep[x] + 1;         dfs(it);         sz[x] += sz[it];       }     }   }   void per_dfs(int x) {     vis[x] = 1;     root[x] = update(root[p[0][x]], 1, m, yr[x]);     for (auto it : g[x]) {       if (!vis[it]) {         per_dfs(it);       }     }   }   int lca(int u, int v) {     if (dep[u] < dep[v]) swap(u, v);     int diff = dep[u] - dep[v];     for (int i = 0; i < 18; i++) {       if ((diff >> i) & 1) u = p[i][u];     }     if (u == v) return u;     for (int i = 17; i > -1; i--) {       if (p[i][u] != p[i][v]) {         u = p[i][u];         v = p[i][v];       }     }     return p[0][u];   }   void HLD(int x) {     if (chainhd[num] == 0) chainhd[num] = x;     pos[x] = cur;     rpos[cur] = x;     cur++;     chain[x] = num;     int mx = 0, hv = -1;     for (auto it : g[x]) {       if (it != p[0][x]) {         if (sz[it] >= mx) {           mx = sz[it];           hv = it;         }       }     }     if (hv == -1) return;     HLD(hv);     for (auto it : g[x]) {       if (it != hv and it != p[0][x]) {         num++;         HLD(it);       }     }   }   int per_query(int id, int x, int y, int l, int r) {     if (l > y or r < x) return 0;     if (l <= x and r >= y) return t[id];     int mid = (x + y) >> 1;     int ans = per_query(L[id], x, mid, l, r) + per_query(R[id], mid + 1, y, l, r);     return ans;   }   int search(int u, int l, int r, int k, int y, int i) {     if (k == 1 and (yr[u] <= y or yr[u] >= i)) return u;     while (l < r) {       int mid = (l + r) >> 1;       int node = rpos[mid];       int x = per_query(root[u], 1, m, y + 1, i) -               per_query(root[node], 1, m, y + 1, i);       x = dep[u] - dep[node] - x;       if (yr[node] <= y or yr[node] >= i) x++;       if (x >= k) {         l = mid + 1;       } else {         r = mid;       }     }     return rpos[l - 1];   }   int query_hld(int u, int v, int k, int y, int i) {     u = p[0][u];     int a = chain[u], b = chain[v];     while (a != b) {       int hd = chainhd[a];       int x = per_query(root[u], 1, m, y + 1, i) -               per_query(root[hd], 1, m, y + 1, i);       if (yr[hd] >= y + 1 and yr[hd] < i) x++;       x = dep[u] - dep[hd] + 1 - x;       if (x >= k) {         int l = pos[hd], r = pos[u];         return search(u, l, r, k, y, i);       } else {         k -= x;         u = p[0][hd];         a = chain[u];       }     }     if (u == v) {       return -1;     }     int l = pos[v] + 1, r = pos[u];     return search(u, l, r, k, y, i);   }   int count(int u, int v, int y, int i) {     u = p[0][u];     if (dep[u] <= dep[v]) return 0;     int ans =         per_query(root[u], 1, m, y + 1, i) - per_query(root[v], 1, m, y + 1, i);     ans = dep[u] - dep[v] - ans;     return ans;   }   int main() {     scanf( %d , &n);     for (int i = 1; i <= n; i++) {       scanf( %d , &p[0][i]);       if (p[0][i] == 0) {         rt = i;         continue;       }       g[p[0][i]].push_back(i);     }     for (int i = 1; i < 18; i++) {       for (int j = 1; j <= n; j++) {         if (p[i - 1][j] > 0) p[i][j] = p[i - 1][p[i - 1][j]];       }     }     dep[rt] = 1;     dfs(rt);     HLD(rt);     scanf( %d , &m);     build(nxt++, 1, m);     int ty;     for (int i = 1; i <= m; i++) {       scanf( %d , &ty);       if (ty == 1) {         scanf( %d , &ty);         yr[ty] = i;         query[i] = 0;       } else {         query[i] = 1;         scanf( %d%d%d%d , a + i, b + i, k + i, y + i);       }     }     memset(vis, 0, sizeof(vis));     root[0] = 1;     pos[0] = 0;     chain[0] = 0;     per_dfs(rt);     for (int i = 1; i <= m; i++) {       if (query[i]) {         int l = lca(a[i], b[i]);         if (a[i] == l) {           int x = count(b[i], l, y[i], i);           int ans;           if (x >= k[i]) {             ans = query_hld(b[i], l, x - k[i] + 1, y[i], i);           } else {             ans = -1;           }           printf( %d n , ans);         } else if (b[i] == l) {           int x = count(a[i], l, y[i], i);           int ans;           if (x >= k[i]) {             ans = query_hld(a[i], l, k[i], y[i], i);           } else {             ans = -1;           }           printf( %d n , ans);         } else {           int x = count(a[i], l, y[i], i);           int ans;           if (x >= k[i]) {             ans = query_hld(a[i], l, k[i], y[i], i);           } else {             k[i] -= x;             if (yr[l] <= y[i] or yr[l] >= i) k[i]--;             if (k[i] == 0)               ans = l;             else {               x = count(b[i], l, y[i], i);               if (x >= k[i])                 ans = query_hld(b[i], l, x - k[i] + 1, y[i], i);               else                 ans = -1;             }           }           printf( %d n , ans);         }       }     }   }   