#include <bits/stdc++.h>
inline int max(int x, int y) { return x > y ? x : y; }
struct request {
  int node, time, id;
} p[200001];
int N, M, J[18][200001],
    *fa = J[0], dep[200001], ALL_LOG, head[200001], next[200001], size[200001],
    son[200001], left[200001], right[200001], top[200001], ref[200002],
    q[200002], ue[200002], T[524289], SIZE[524289], TAG[524289], LEFT[524289],
    GAP[524289], ANS[200001];
inline bool operator<(const request &a, const request &b) {
  return a.time + dep[a.node] < b.time + dep[b.node] ||
         a.time + dep[a.node] == b.time + dep[b.node] && a.node < b.node;
}
void READ() {
  scanf("%d%d", &N, &M);
  for (int i = 1; i <= N; i++) {
    scanf("%d", fa + i);
    dep[i] = dep[fa[i]] + 1;
    next[i] = head[fa[i]], head[fa[i]] = i;
  }
  while (2 << ALL_LOG < N) ALL_LOG++;
  for (int i = 1; i <= ALL_LOG; i++)
    for (int j = 1; j <= N; j++) J[i][j] = J[i - 1][J[i - 1][j]];
  for (int i = 1; i <= M; i++) {
    scanf("%d%d", &p[i].node, &p[i].time);
    p[i].id = i;
  }
  std::sort(p + 1, p + M + 1);
}
void BFSDFS() {
  int *H = q, *T = q + 1;
  q[1] = 0;
  while (H < T)
    for (int u = *++H, e = head[u]; e; e = next[e]) *++T = e;
  for (int i = N + 1; i > 1; i--) {
    size[fa[q[i]]] += ++size[q[i]];
    if (!son[fa[q[i]]] || size[q[i]] > size[son[fa[q[i]]]])
      son[fa[q[i]]] = q[i];
  }
  size[0]++;
  q[1] = 0, ue[1] = head[0];
  top[0] = 0;
  int D = 1, TIME = 1;
  left[0] = right[0] = 1;
  ref[1] = 0;
  top[0] = 0;
  while (D)
    if (son[q[D]] && !left[son[q[D]]]) {
      int To = son[q[D]];
      ref[left[To] = right[To] = ++TIME] = To;
      top[To] = top[q[D]];
      q[++D] = To, ue[D] = head[To];
    } else {
      if (ue[D] && ue[D] == son[q[D]]) ue[D] = next[ue[D]];
      if (ue[D]) {
        int To = ue[D];
        ue[D] = next[ue[D]];
        ref[left[To] = right[To] = ++TIME] = To;
        top[To] = To;
        q[++D] = To, ue[D] = head[To];
      } else {
        if (D > 1) right[q[D - 1]] = right[q[D]];
        D--;
      }
    }
}
void TREEinit(int p, int l, int r) {
  SIZE[p] = r - l + 1;
  if (l < r) {
    int m = l + r >> 1;
    TREEinit(p << 1, l, m);
    TREEinit(p << 1 | 1, m + 1, r);
  }
}
inline void EAT(int p, int left, int gap) {
  LEFT[p] = left;
  GAP[p] = gap;
  TAG[p] = 1;
  T[p] = gap >= 0 ? left + (SIZE[p] - 1) * gap : left;
}
inline void DOWN(int p) {
  if (TAG[p]) {
    EAT(p << 1, LEFT[p], GAP[p]);
    EAT(p << 1 | 1, LEFT[p] + SIZE[p << 1] * GAP[p], GAP[p]);
    TAG[p] = 0;
  }
}
inline void UP(int p) { T[p] = max(T[p << 1], T[p << 1 | 1]); }
void COVER(int p, int l, int r, int L, int R, int LEFT, int GAP) {
  if (l == L && r == R)
    EAT(p, LEFT, GAP);
  else {
    int m = l + r >> 1;
    DOWN(p);
    if (R <= m)
      COVER(p << 1, l, m, L, R, LEFT, GAP);
    else if (L > m)
      COVER(p << 1 | 1, m + 1, r, L, R, LEFT, GAP);
    else {
      COVER(p << 1, l, m, L, m, LEFT, GAP);
      COVER(p << 1 | 1, m + 1, r, m + 1, R, LEFT + GAP * (m - L + 1), GAP);
    }
    UP(p);
  }
}
int GET(int p, int l, int r, int L, int R) {
  if (L <= l && r <= R) return T[p];
  int m = l + r >> 1;
  DOWN(p);
  if (R <= m)
    return GET(p << 1, l, m, L, R);
  else if (L > m)
    return GET(p << 1 | 1, m + 1, r, L, R);
  else
    return max(GET(p << 1, l, m, L, R), GET(p << 1 | 1, m + 1, r, L, R));
}
void ANSWER(int id, int node, int time) {
  int target = node;
  while (GET(1, 1, N + 1, left[top[target]], left[target]) <= time + dep[node])
    target = fa[top[target]];
  int MAXDEP = dep[target] - dep[top[target]] + 1, LOG = 1;
  while (2 << LOG <= MAXDEP) LOG++;
  for (int i = LOG; ~i; i--)
    if (GET(1, 1, N + 1, left[target] - (1 << i) + 1, left[target]) <=
        time + dep[node])
      target = J[i][target];
  ANS[id] = time + (dep[node] - dep[target] << 1);
  int changed = node;
  while (top[changed] != top[target]) {
    COVER(1, 1, N + 1, left[top[changed]], left[changed],
          time + dep[node] + (dep[top[changed]] - dep[target] << 1), 2);
    changed = fa[top[changed]];
  }
  if (changed != target)
    COVER(1, 1, N + 1, left[target] + 1, left[changed], time + dep[node] + 2,
          2);
}
int main() {
  READ();
  BFSDFS();
  TREEinit(1, 1, N + 1);
  COVER(1, 1, N + 1, 1, 1, 2000000000, 0);
  for (int i = 1; i <= M; i++) ANSWER(p[i].id, p[i].node, p[i].time);
  for (int i = 1; i <= M; i++) printf("%d%c", ANS[i], " \n"[i == M]);
  return 0;
}
