func_code_string: #include <bits/stdc++.h>   using namespace std;   const int N = 3e5 + 5;   const long long INF = 2e9;   int n, m, dp[N], d[N], og[N], son[N], pr[N], top[N], num[N], sz, p[N], ans[N],       a[N], b[N];   int t[5 * N], ob[5 * N];   vector<int> g[N];   void build(int v, int l, int r) {     ob[v] = -1;     if (l == r) {       if (l == 1) {         t[v] = INF;       }       return;     }     int mid = (r + l) >> 1;     build(v + v, l, mid);     build(v + v + 1, mid + 1, r);     t[v] = max(t[v + v], t[v + v + 1]);   }   inline void push(int v, int l, int r) {     if (ob[v] != -1) {       ob[v + v + 1] = t[v + v + 1] = ob[v];       int mid = (r + l) >> 1;       ob[v + v] = t[v + v] = ob[v] - 2 * (r - mid);       ob[v] = -1;     }   }   int mx(int v, int l, int r, int tl, int tr) {     push(v, l, r);     if (l > r || l > tr || tl > r) {       return -INF;     }     if (tl <= l && r <= tr) {       return t[v];     }     int mid = (r + l) >> 1;     return max(mx(v + v, l, mid, tl, tr), mx(v + v + 1, mid + 1, r, tl, tr));   }   int get(int v, int l, int r, int tl, int tr, int val) {     push(v, l, r);     if (t[v] <= val || l > r || l > tr || tl > r) {       return -1;     }     if (l == r) {       return og[l];     }     int mid = (r + l) >> 1;     int y = get(v + v + 1, mid + 1, r, tl, tr, val);     return y == -1 ? get(v + v, l, mid, tl, tr, val) : y;   }   void update(int v, int l, int r, int tl, int tr, int val) {     push(v, l, r);     if (l > r || l > tr || tl > r) {       return;     }     if (tl <= l && r <= tr) {       t[v] = ob[v] = val - 2 * (tr - r);       return;     }     int mid = (r + l) >> 1;     update(v + v, l, mid, tl, tr, val);     update(v + v + 1, mid + 1, r, tl, tr, val);     t[v] = max(t[v + v], t[v + v + 1]);   }   void dfs(int v, int depth = 0) {     dp[v] = 1;     d[v] = depth;     for (int to : g[v]) {       dfs(to, depth + 1);       pr[to] = v;       dp[v] += dp[to];       if (!son[v] || (dp[to] > dp[son[v]])) {         son[v] = to;       }     }   }   void hld(int v) {     sz++;     og[sz] = v;     num[v] = sz;     if (son[v]) {       top[son[v]] = top[v];       hld(son[v]);     }     for (int to : g[v]) {       if (to != son[v]) {         top[to] = to;         hld(to);       }     }   }   inline bool cmp(int x, int y) {     return d[a[x]] + b[x] < d[a[y]] + b[y] ||            (d[a[x]] + b[x] == d[a[y]] + b[y] && a[x] < a[y]);   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 1; i <= n; i++) {       int x;       scanf( %d , &x);       g[x].push_back(i);     }     dfs(0);     hld(0);     n++;     build(1, 1, n);     for (int i = 1; i <= m; i++) {       scanf( %d%d , &a[i], &b[i]);       p[i] = i;     }     sort(p + 1, p + m + 1, cmp);     for (int i = 1; i <= m; i++) {       int x = a[p[i]], t = b[p[i]], v;       while (true) {         if (mx(1, 1, n, num[top[x]], num[x]) > t + d[a[p[i]]]) {           v = get(1, 1, n, num[top[x]], num[x], t + d[a[p[i]]]);           break;         }         x = pr[top[x]];       }       ans[p[i]] = t + 2 * (d[a[p[i]]] - d[v]);       x = a[p[i]];       while (true) {         if (mx(1, 1, n, num[top[x]], num[x]) > t + d[a[p[i]]]) {           v = get(1, 1, n, num[top[x]], num[x], t + d[a[p[i]]]);           if (v != x) {             update(1, 1, n, num[v] + 1, num[x],                    ans[p[i]] - (d[a[p[i]]] - d[x]) + d[x]);           }           break;         } else {           update(1, 1, n, num[top[x]], num[x],                  ans[p[i]] - (d[a[p[i]]] - d[x]) + d[x]);         }         x = pr[top[x]];       }     }     for (int i = 1; i <= m; i++) {       printf( %d  , ans[i]);     }   }   