#include <bits/stdc++.h>
using namespace std;
int read() {
  char ch = getchar();
  int h = 0, t = 1;
  while ((ch > '9' || ch < '0') && ch != '-') ch = getchar();
  if (ch == '-') t = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') h = h * 10 + ch - '0', ch = getchar();
  return h * t;
}
const int N = 201000;
struct edge {
  int next, to;
} a[N << 1];
struct Que {
  int x, st, id, T;
} A[N];
int n, m, head[N], cnt, dep[N], dfn[N], top[N], id[N], fa[N], siz[N], son[N],
    tot;
int cmp1(const Que &A, const Que &B) {
  return (A.st + dep[A.x] < B.st + dep[B.x]) |
         (A.st + dep[A.x] == B.st + dep[B.x] && A.x < B.x);
}
int cmp2(const Que &A, const Que &B) { return A.id < B.id; }
void link(int x, int y) {
  a[++cnt] = (edge){head[x], y};
  head[x] = cnt;
}
void dfs1(int x) {
  siz[x] = 1;
  dep[x] = dep[fa[x]] + 1;
  for (int i = head[x]; i; i = a[i].next) {
    int R = a[i].to;
    if (R == fa[x]) continue;
    dfs1(R);
    siz[x] += siz[R];
    if (siz[R] > siz[son[x]]) son[x] = R;
  }
}
void dfs2(int x) {
  top[x] = x;
  dfn[x] = ++tot;
  id[tot] = x;
  if (son[fa[x]] == x) top[x] = top[fa[x]];
  if (son[x]) dfs2(son[x]);
  for (int i = head[x]; i; i = a[i].next)
    if (a[i].to != fa[x] && a[i].to != son[x]) dfs2(a[i].to);
}
int t[N << 3], T[N << 3], lz[N << 3];
void Max(int &a, int b) {
  if (b > a) a = b;
}
void Build(int now, int l, int r) {
  T[now] = lz[now] = -1e9;
  if (l == r) {
    t[now] = 2 * dep[id[l]];
    return;
  }
  int mid = (l + r) >> 1;
  Build(now << 1, l, mid);
  Build(now << 1 | 1, mid + 1, r);
  t[now] = max(t[now << 1], t[now << 1 | 1]);
}
void put(int x, int k) {
  T[x] = t[x] + k;
  lz[x] = k;
}
void pushdown(int x) {
  int &s = lz[x];
  if (s == -1e9) return;
  put(x << 1, s);
  put(x << 1 | 1, s);
  s = -1e9;
}
void Cover(int now, int l, int r, int gl, int gr, int k) {
  if (l >= gl && r <= gr) {
    put(now, k);
    return;
  }
  pushdown(now);
  int mid = (l + r) >> 1;
  if (gl <= mid) Cover(now << 1, l, mid, gl, gr, k);
  if (gr > mid) Cover(now << 1 | 1, mid + 1, r, gl, gr, k);
  T[now] = max(T[now << 1], T[now << 1 | 1]);
}
int Query(int now, int l, int r, int gl, int gr) {
  if (l >= gl && r <= gr) return T[now];
  int mid = (l + r) >> 1, res = -1e9;
  pushdown(now);
  if (gl <= mid) Max(res, Query(now << 1, l, mid, gl, gr));
  if (gr > mid) Max(res, Query(now << 1 | 1, mid + 1, r, gl, gr));
  return res;
}
int main() {
  n = read() + 1;
  m = read();
  if (!m) return 0;
  for (int i = 2; i <= n; i++) fa[i] = read() + 1, link(fa[i], i);
  for (int i = 1, x, st; i <= m; i++)
    x = read() + 1, st = read(), A[i] = (Que){x, st, i, -1};
  dfs1(1);
  dfs2(1);
  sort(A + 1, A + m + 1, cmp1);
  Build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    int x = A[i].x, tt = x, res = 0;
    if (Query(1, 1, n, dfn[x], dfn[x]) > A[i].st + dep[x]) {
      A[i].T = A[i].st;
      continue;
    }
    while (tt) {
      int mx = Query(1, 1, n, dfn[top[tt]], dfn[tt]);
      if (mx <= dep[x] + A[i].st) {
        res = top[tt], tt = fa[top[tt]];
        continue;
      }
      int l = dfn[top[tt]], r = dfn[tt];
      while (l <= r) {
        int mid = (l + r) >> 1;
        mx = Query(1, 1, n, mid, r);
        if (mx <= dep[x] + A[i].st)
          res = id[mid], r = mid - 1;
        else
          l = mid + 1;
      }
      break;
    }
    A[i].T = A[i].st + 2 * (dep[x] - dep[tt ? fa[res] : 1]);
    int kk = A[i].st + dep[x] - 2 * dep[tt ? fa[res] : 1];
    if (tt) Cover(1, 1, n, dfn[res], dfn[tt], kk);
    while (x != tt) {
      Cover(1, 1, n, dfn[top[x]], dfn[x], kk);
      x = fa[top[x]];
    }
  }
  sort(A + 1, A + m + 1, cmp2);
  for (int i = 1; i <= m; i++) printf("%d ", A[i].T);
  return 0;
}
