func_code_string: #include <bits/stdc++.h>   const int N = 100005;   int n, fa[N], rt, cnt = 0, sz[N], son[N] = {0}, top[N], dep[N], idx = 0, Q,                     dfn[N], head[N], hq[N], nodes = 0, year[N];   int ret, L, R;   inline int readint() {     int c = getchar(), d = 0;     for (; !isdigit(c); c = getchar())       ;     for (; isdigit(c); c = getchar()) d = (d << 3) + (d << 1) + (c ^  0 );     return d;   }   struct edge {     int to, nxt;   } e[N << 1];   struct SegmentTreeNode {     int v, ls, rs, l, r, sz;   } d[N << 5];   void BigMagician(int now) {     sz[now] = 1;     for (int i = head[now]; i; i = e[i].nxt)       if (fa[e[i].to] == now) {         dep[e[i].to] = dep[now] + 1;         BigMagician(e[i].to);         sz[now] += sz[e[i].to];         if (!son[now] || sz[e[i].to] > sz[son[now]]) son[now] = e[i].to;       }   }   void dfs(int now) {     dfn[now] = ++idx;     hq[idx] = now;     if (son[now]) top[son[now]] = top[now], dfs(son[now]);     for (int i = head[now]; i; i = e[i].nxt)       if (dep[now] < dep[e[i].to] && e[i].to != son[now])         dfs(top[e[i].to] = e[i].to);   }   void build(int l, int r, int& o) {     o = ++nodes;     d[o].l = l, d[o].r = r, d[o].sz = r - l + 1;     if (l == r)       d[o].v = 1;     else {       int mid = l + r >> 1;       build(l, mid, d[o].ls);       build(mid + 1, r, d[o].rs);       d[o].v = d[d[o].ls].v + d[d[o].rs].v;     }   }   void modify(int o, int& nw, int& p) {     d[nw = ++nodes] = d[o];     --d[nw].v;     if (d[o].l != d[o].r) {       int mid = d[o].l + d[o].r >> 1;       if (p <= mid)         modify(d[o].ls, d[nw].ls, p);       else         modify(d[o].rs, d[nw].rs, p);     }   }   void query(int& o, int& nw) {     if (L <= d[o].l && d[o].r <= R)       ret += d[o].v - d[nw].v;     else {       int mid = d[d[o].ls].r;       if (L <= mid) query(d[o].ls, d[nw].ls);       if (mid < R) query(d[o].rs, d[nw].rs);     }   }   void query2(int& o, int& nw, int k) {     if (d[o].l == d[o].r)       ret = hq[d[o].l];     else {       if (k <= d[d[o].rs].sz - d[d[o].rs].v + d[d[nw].rs].v)         query2(d[o].rs, d[nw].rs, k);       else         query2(d[o].ls, d[nw].ls,                k - (d[d[o].rs].sz - d[d[o].rs].v + d[d[nw].rs].v));     }   }   inline int theLCA(int x, int y) {     for (; top[x] != top[y];)       if (dep[top[x]] >= dep[top[y]])         x = fa[top[x]];       else         y = fa[top[y]];     return (dep[x] < dep[y]) ? x : y;   }   inline int search_to_lca(int u, int v, int& k, int& y, int& nw) {     while (top[u] != top[v]) {       ret = 0;       L = dfn[top[u]], R = dfn[u];       query(y, nw);       ret = R - L + 1 - ret;       if (ret >= k) {         ret = 0;         L = dfn[u] + 1, R = n;         if (L <= n) query(y, nw);         ret = R - L + 1 - ret;         k += ret;         ret = 0;         query2(y, nw, k);         return ret;       }       k -= ret;       u = fa[top[u]];     }     ret = 0;     L = dfn[v], R = dfn[u];     query(y, nw);     ret = R - L + 1 - ret;     if (ret >= k) {       ret = 0;       L = dfn[u] + 1, R = n;       if (L <= n) query(y, nw);       ret = R - L + 1 - ret;       k += ret;       ret = 0;       query2(y, nw, k);       return ret;     }     k -= ret;     return -1;   }   inline int search_on_a_list(int u, int v, int& y, int& nw) {     int ans = 0;     while (top[u] != top[v]) {       ret = 0;       L = dfn[top[u]], R = dfn[u];       query(y, nw);       ret = R - L + 1 - ret;       ans += ret;       u = fa[top[u]];     }     ret = 0;     L = dfn[v], R = dfn[u];     query(y, nw);     ret = R - L + 1 - ret;     return ans + ret;   }   inline int search_from_lca(int u, int v, int& k, int& y, int& nw) {     int all = search_on_a_list(u, v, y, nw);     if (all < k) return -1;     k = all - k + 1;     while (top[u] != top[v]) {       ret = 0;       L = dfn[top[u]], R = dfn[u];       query(y, nw);       ret = R - L + 1 - ret;       if (ret >= k) {         ret = 0;         L = dfn[u] + 1, R = n;         if (L <= n) query(y, nw);         ret = R - L + 1 - ret;         k += ret;         ret = 0;         query2(y, nw, k);         return ret;       }       k -= ret;       u = fa[top[u]];     }     ret = 0;     L = dfn[v], R = dfn[u];     query(y, nw);     ret = R - L + 1 - ret;     if (ret >= k) {       ret = 0;       L = dfn[u] + 1, R = n;       if (L <= n) query(y, nw);       ret = R - L + 1 - ret;       k += ret;       ret = 0;       query2(y, nw, k);       return ret;     }     k -= ret;     return -1;   }   int main() {     memset(head, 0, sizeof head);     n = readint();     for (int i = 1; i <= n; ++i) {       fa[i] = readint();       if (!fa[i])         rt = i;       else {         e[++cnt] = (edge){i, head[fa[i]]};         head[fa[i]] = cnt;         e[++cnt] = (edge){fa[i], head[i]};         head[i] = cnt;       }     }     dep[rt] = 1;     top[rt] = rt;     BigMagician(rt);     dfs(rt);     build(1, n, year[0]);     Q = readint();     for (int i = 1; i <= Q; ++i) {       int opt = readint();       if (opt == 1) {         int p = readint();         modify(year[i - 1], year[i], dfn[p]);       } else {         year[i] = year[i - 1];         int u = readint(), v = readint(), k = readint(), y = readint();         ret = 0;         L = R = dfn[u];         query(year[y], year[i]);         if (!ret) ++k;         int lca = theLCA(u, v);         int ans = search_to_lca(u, lca, k, year[y], year[i]);         if (!~ans) {           ret = 0;           L = R = dfn[lca];           query(year[y], year[i]);           if (!ret) ++k;           ans = search_from_lca(v, lca, k, year[y], year[i]);         }         if (ans == v || ans == u) ans = -1;         printf( %d n , ans);       }     }     return 0;   }   