#include <bits/stdc++.h>   using namespace std;   inline int read() {     int x = 0, f = 1;     char ch = getchar();     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) f = -1;       ch = getchar();     }     while (ch >=  0  && ch <=  9 ) {       x = x * 10 + ch -  0 ;       ch = getchar();     }     return x * f;   }   void write(int x) {     if (x > 9) write(x / 10);     putchar(x % 10 +  0 );   }   const int N = 200005, inf = 1e9;   int a[N], t[N], id[N], fa[N], dep[N], num[N], son[N], q[N], dfn[N];   int top[N], ans[N], n, m, cnt = 0, fd;   struct tree {     int mx, lazy;   } tr[N << 2];   bool cmp(int x, int y) {     if (t[x] + dep[a[x]] != t[y] + dep[a[y]])       return t[x] + dep[a[x]] < t[y] + dep[a[y]];     return a[x] < a[y];   }   inline void pushup(int x) { tr[x].mx = max(tr[x << 1].mx, tr[x << 1 | 1].mx); }   inline void pushdown(int x, int l, int mid, int r) {     if (tr[x].lazy < -inf) return;     tr[x << 1].lazy = tr[x << 1 | 1].lazy = tr[x].lazy;     tr[x << 1].mx = mid * 2 + tr[x].lazy;     tr[x << 1 | 1].mx = r * 2 + tr[x].lazy;     tr[x].lazy = -inf - 1;   }   void modify(int now, int l, int r, int x, int y, int z) {     if (x <= l && r <= y) {       tr[now].lazy = z;       tr[now].mx = r * 2 + z;       return;     }     int mid = (l + r) >> 1;     pushdown(now, l, mid, r);     if (x <= mid) modify(now << 1, l, mid, x, y, z);     if (y > mid) modify(now << 1 | 1, mid + 1, r, x, y, z);     pushup(now);   }   void query(int now, int l, int r, int x, int y, int z) {     if (tr[now].mx <= z) return;     if (l == r) {       fd = q[l];       return;     }     int mid = (l + r) >> 1;     pushdown(now, l, mid, r);     if (fd == -1 && y > mid) query(now << 1 | 1, mid + 1, r, x, y, z);     if (fd == -1 && x <= mid) query(now << 1, l, mid, x, y, z);     pushup(now);   }   int work(int x, int t) {     int y = x;     while (1) {       fd = -1;       query(1, 0, n, dfn[top[y]], dfn[y], t + dfn[y]);       if (fd >= 0) {         t += dep[y] - dep[fd];         y = fd;         break;       }       if (!y) break;       t += dep[y] - dep[fa[top[y]]];       y = fa[top[y]];     }     int z = t + dep[x] - dep[y];     while (1) {       if (top[x] == top[y]) {         if (x != y) modify(1, 0, n, dfn[y] + 1, dfn[x], t - dfn[y]);         break;       }       modify(1, 0, n, dfn[top[x]], dfn[x], dep[x] - dep[y] + t - dfn[x]);       x = fa[top[x]];     }     return z;   }   int main() {     n = read();     m = read();     for (int i = 1; i <= n; ++i) {       fa[i] = read();       dep[i] = dep[fa[i]] + 1;       num[i] = 1;     }     for (int i = n; i; i--) {       if (num[i] > num[son[fa[i]]]) son[fa[i]] = i;       if (fa[i]) num[fa[i]] += num[i];     }     for (int i = son[0]; i; i = son[i]) q[dfn[i] = ++cnt] = i;     for (int i = 0; i <= n; ++i)       if (!dfn[i])         for (int j = i; j; j = son[j]) top[q[dfn[j] = ++cnt] = j] = i;     for (int i = 1; i <= m; ++i) a[i] = read(), t[i] = read();     for (int i = 1; i <= m; ++i) id[i] = i;     sort(id + 1, id + m + 1, cmp);     tr[1].mx = tr[1].lazy = -inf;     for (int i = 1; i <= m; ++i) ans[id[i]] = work(a[id[i]], t[id[i]]);     for (int i = 1; i <= m; ++i) write(ans[i]), putchar(   );     puts(  );     return 0;   }