#include <bits/stdc++.h>
using namespace std;
int IN() {
  int x = 0, f = 0, ch;
  for (; (ch = getchar()) < '0' || ch > '9';) f = (ch == '-');
  for (; ch >= '0' && ch <= '9'; (ch = getchar())) x = x * 10 + ch - '0';
  return f ? -x : x;
}
int N, M, F[200005], Dep[200005], Ans[200005];
struct Opt {
  int x, t, ID;
} G[200005];
bool Cmp(const Opt& a, const Opt& b) {
  if (Dep[a.x] + a.t != Dep[b.x] + b.t) return Dep[a.x] + a.t < Dep[b.x] + b.t;
  return a.x < b.x;
}
int C, D, st[200005], son[200005], siz[200005], Top[200005], Dfn[200005],
    Seq[200005];
struct Lin {
  int v, next;
} E[200005];
void Link(int u, int v) {
  E[++D] = (Lin){v, st[u]};
  st[u] = D;
}
void DFS1(int u) {
  siz[u] = 1;
  for (int i = st[u], v; i; i = E[i].next) {
    DFS1(v = E[i].v);
    siz[u] += siz[v];
    if (siz[v] > siz[son[u]]) son[u] = v;
  }
}
void DFS2(int u, int c) {
  Dfn[u] = ++C;
  Seq[C] = u;
  Top[u] = c;
  if (son[u]) DFS2(son[u], c);
  for (int i = st[u], v; i; i = E[i].next)
    if ((v = E[i].v) != son[u]) DFS2(v, v);
}
int T[200005 << 2], Cov[200005 << 2], MD[200005 << 2];
void Upd(int u, int val) {
  Cov[u] = val;
  T[u] = val + MD[u];
}
void Down(int u) {
  if (Cov[u] != -(1 << 30)) {
    Upd(u << 1, Cov[u]);
    Upd(u << 1 | 1, Cov[u]);
    Cov[u] = -(1 << 30);
  }
}
void Up(int u) { T[u] = max(T[u << 1], T[u << 1 | 1]); }
void Build(int u, int l, int r) {
  Cov[u] = T[u] = -(1 << 30);
  if (l == r) {
    MD[u] = 2 * Dep[Seq[l]];
    return;
  }
  int Mid = (l + r) >> 1;
  Build(u << 1, l, Mid);
  Build(u << 1 | 1, Mid + 1, r);
  MD[u] = max(MD[u << 1], MD[u << 1 | 1]);
}
int Query(int u, int l, int r, int x, int y) {
  if (x <= l && r <= y) return T[u];
  int Mid = (l + r) >> 1;
  Down(u);
  if (y <= Mid) return Query(u << 1, l, Mid, x, y);
  if (x > Mid) return Query(u << 1 | 1, Mid + 1, r, x, y);
  return max(Query(u << 1, l, Mid, x, y), Query(u << 1 | 1, Mid + 1, r, x, y));
}
int Find(int u, int l, int r, int x, int y, int val) {
  if (T[u] <= val) return -1;
  if (l == r) return Seq[l];
  int Mid = (l + r) >> 1;
  Down(u);
  if (y <= Mid) return Find(u << 1, l, Mid, x, y, val);
  if (x > Mid) return Find(u << 1 | 1, Mid + 1, r, x, y, val);
  int t = Find(u << 1 | 1, Mid + 1, r, x, y, val);
  if (t == -1) return Find(u << 1, l, Mid, x, y, val);
  return t;
}
int Ask(int x, int val) {
  int ret = x;
  for (; x != -1;) {
    int y = Top[x];
    if (Query(1, 1, C, Dfn[y], Dfn[x]) <= val)
      ret = y, x = F[y];
    else {
      int t = Find(1, 1, C, Dfn[y], Dfn[x], val);
      if (t != x) ret = son[t];
      break;
    }
  }
  return ret;
}
void Modify(int u, int l, int r, int x, int y, int val) {
  if (x <= l && r <= y) return Upd(u, val);
  int Mid = (l + r) >> 1;
  Down(u);
  if (x <= Mid) Modify(u << 1, l, Mid, x, y, val);
  if (y > Mid) Modify(u << 1 | 1, Mid + 1, r, x, y, val);
  Up(u);
}
void Add(int x, int z, int val) {
  for (; Top[x] != Top[z];) {
    int y = Top[x];
    Modify(1, 1, C, Dfn[y], Dfn[x], val);
    x = F[y];
  }
  Modify(1, 1, C, Dfn[z], Dfn[x], val);
}
int main(int argc, char* argv[]) {
  N = IN();
  M = IN();
  for (int i = 1, lim = N; i <= lim; i++)
    F[i] = IN(), Dep[i] = Dep[F[i]] + 1, Link(F[i], i);
  F[0] = -1;
  DFS1(0);
  DFS2(0, 0);
  Build(1, 1, C);
  for (int i = 1, lim = M; i <= lim; i++) G[i] = (Opt){IN(), IN(), i};
  sort(G + 1, G + M + 1, Cmp);
  for (int i = 1, lim = M; i <= lim; i++) {
    int x = G[i].x;
    if (G[i].t + Dep[x] < Query(1, 1, C, Dfn[x], Dfn[x]))
      Ans[G[i].ID] = G[i].t;
    else {
      int y = Ask(x, G[i].t + Dep[x]), z = y ? F[y] : y;
      Ans[G[i].ID] = G[i].t + 2 * (Dep[x] - Dep[z]);
      Add(x, y, G[i].t + (Dep[x] - Dep[z]) - Dep[z]);
    }
  }
  for (int i = 1, lim = M; i <= lim; i++) printf("%d ", Ans[i]);
  puts("");
  return 0;
}
