#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
const int inf = 2000000000;
int n, m, cnt;
int to[maxn], nxt[maxn], head[maxn], fa[maxn], p[maxn], q[maxn], dep[maxn],
    siz[maxn], son[maxn], top[maxn];
int sd[maxn << 2], s[maxn << 2], tag[maxn << 2], ans[maxn];
struct node {
  int x, t, org;
} t[maxn];
void dfs(int x, int tp) {
  top[x] = tp;
  p[x] = ++q[0], q[q[0]] = x;
  if (son[x]) dfs(son[x], tp);
  for (int i = head[x]; i != -1; i = nxt[i])
    if (to[i] != son[x]) dfs(to[i], to[i]);
}
inline void add(int a, int b) {
  to[cnt] = b, nxt[cnt] = head[a], head[a] = cnt++;
}
void build(int l, int r, int x) {
  s[x] = tag[x] = -inf;
  if (l == r) {
    sd[x] = dep[q[l]] << 1;
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
  sd[x] = max(sd[x << 1], sd[x << 1 | 1]);
}
inline void upd(int x, int y) {
  s[x] = max(s[x], sd[x] + y), tag[x] = max(tag[x], y);
}
inline void pushdown(int x) {
  if (tag[x] != -inf)
    upd(x << 1, tag[x]), upd(x << 1 | 1, tag[x]), tag[x] = -inf;
}
void updata(int l, int r, int x, int a, int b, int c) {
  if (a <= l && r <= b) {
    upd(x, c);
    return;
  }
  pushdown(x);
  int mid = (l + r) >> 1;
  if (a <= mid) updata(l, mid, x << 1, a, b, c);
  if (b > mid) updata(mid + 1, r, x << 1 | 1, a, b, c);
  s[x] = max(s[x << 1], s[x << 1 | 1]);
}
int query(int l, int r, int x, int a, int b) {
  if (a <= l && r <= b) return s[x];
  pushdown(x);
  int mid = (l + r) >> 1;
  if (b <= mid) return query(l, mid, x << 1, a, b);
  if (a > mid) return query(mid + 1, r, x << 1 | 1, a, b);
  return max(query(l, mid, x << 1, a, b), query(mid + 1, r, x << 1 | 1, a, b));
}
bool cmp(const node &a, const node &b) {
  return (dep[a.x] + a.t == dep[b.x] + b.t) ? (a.x < b.x)
                                            : (dep[a.x] + a.t < dep[b.x] + b.t);
}
int solve(int x, int t) {
  int u = x;
  while (u) {
    if (query(1, n, 1, p[top[u]], p[u]) <= dep[x] + t) {
      u = fa[top[u]];
      continue;
    }
    int l = p[top[u]] + 1, r = p[u] + 1, mid;
    while (l < r) {
      mid = (l + r) >> 1;
      if (query(1, n, 1, mid, p[u]) > dep[x] + t)
        l = mid + 1;
      else
        r = mid;
    }
    u = q[l - 1];
    break;
  }
  if (!u) u = 1;
  int ret = 2 * (dep[x] - dep[u]) + t, v = x;
  while (top[v] != top[u]) {
    updata(1, n, 1, p[top[v]], p[v], ret - dep[x]), v = fa[top[v]];
  }
  updata(1, n, 1, p[u], p[v], ret - dep[x]);
  return ret;
}
inline int rd() {
  int ret = 0, f = 1;
  char gc = getchar();
  while (gc < '0' || gc > '9') {
    if (gc == '-') f = -f;
    gc = getchar();
  }
  while (gc >= '0' && gc <= '9') ret = ret * 10 + (gc ^ '0'), gc = getchar();
  return ret * f;
}
int main() {
  int i;
  n = rd() + 1, m = rd();
  dep[1] = 1;
  memset(head, -1, sizeof(head));
  for (i = 2; i <= n; i++)
    fa[i] = rd() + 1, add(fa[i], i), dep[i] = dep[fa[i]] + 1;
  for (i = n; i >= 2; i--) {
    siz[i]++, siz[fa[i]] += siz[i];
    if (siz[i] > siz[son[fa[i]]]) son[fa[i]] = i;
  }
  dfs(1, 1);
  build(1, n, 1);
  for (i = 1; i <= m; i++) t[i].x = rd() + 1, t[i].t = rd(), t[i].org = i;
  sort(t + 1, t + m + 1, cmp);
  for (i = 1; i <= m; i++) {
    ans[t[i].org] = solve(t[i].x, t[i].t);
  }
  for (i = 1; i <= m; i++) printf("%d ", ans[i]);
  return 0;
}
