#include <bits/stdc++.h>
using namespace std;
inline char gc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int read() {
  int x = 0;
  char ch = getchar();
  bool positive = 1;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') positive = 0;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return positive ? x : -x;
}
inline void write(int a) {
  if (a >= 10) write(a / 10);
  putchar('0' + a % 10);
}
inline void writeln(int a) {
  if (a < 0) {
    a = -a;
    putchar('-');
  }
  write(a);
  puts("");
}
const int N = 200005, oo = 1e9;
int ans[N], fa[N];
pair<pair<int, int>, int> a[N];
int nedge, wson[N], ed[N], nextt[N], son[N], tree[N << 2], lazy[N << 2], peo[N],
    deep[N], ti, n, m, pos[N], father[N], in[N], top[N];
inline void aedge(int a, int b) {
  nextt[++nedge] = son[a];
  son[a] = nedge;
  ed[nedge] = b;
}
inline void cao(int nod, int r, int x) {
  tree[nod] = x + deep[pos[r]] * 2;
  lazy[nod] = x;
}
inline void pushdown(int nod, int l, int r) {
  if (lazy[nod] == -oo) return;
  int mid = (l + r) >> 1;
  cao(nod << 1, mid, lazy[nod]);
  cao(nod << 1 | 1, r, lazy[nod]);
  lazy[nod] = -oo;
}
inline int ask(int l, int r, int i, int j, int s, int nod) {
  if (l > 1 && tree[nod] <= s) return 0;
  if (l == r) return pos[l];
  pushdown(nod, l, r);
  int mid = (l + r) >> 1;
  if (j <= mid)
    return ask(l, mid, i, j, s, nod << 1);
  else if (i > mid)
    return ask(mid + 1, r, i, j, s, nod << 1 | 1);
  int t = ask(mid + 1, r, mid + 1, j, s, nod << 1 | 1);
  if (t) return t;
  return ask(l, mid, i, mid, s, nod << 1);
}
inline void insert(int l, int r, int i, int j, int s, int nod) {
  if (l == i && r == j) {
    lazy[nod] = s;
    cao(nod, r, s);
    return;
  }
  pushdown(nod, l, r);
  int mid = (l + r) >> 1;
  if (j <= mid)
    insert(l, mid, i, j, s, nod << 1);
  else if (i > mid)
    insert(mid + 1, r, i, j, s, nod << 1 | 1);
  else {
    insert(l, mid, i, mid, s, nod << 1);
    insert(mid + 1, r, mid + 1, j, s, nod << 1 | 1);
  }
  tree[nod] = max(tree[nod << 1], tree[nod << 1 | 1]);
}
void dfs1(int p) {
  peo[p] = 1;
  wson[p] = -1;
  for (int i = son[p]; i; i = nextt[i]) {
    deep[ed[i]] = deep[p] + 1;
    dfs1(ed[i]);
    peo[p] += peo[ed[i]];
    if (wson[p] == -1 || peo[ed[i]] > peo[wson[p]]) wson[p] = ed[i];
  }
}
void dfs2(int p) {
  pos[in[p] = ++ti] = p;
  if (p == wson[father[p]])
    top[p] = top[father[p]];
  else
    top[p] = p;
  if (wson[p] != -1) dfs2(wson[p]);
  for (int i = son[p]; i; i = nextt[i])
    if (ed[i] != wson[p]) dfs2(ed[i]);
}
inline bool cmp(pair<pair<int, int>, int> a, pair<pair<int, int>, int> b) {
  return a.first.second + deep[a.first.first] ==
                 b.first.second + deep[b.first.first]
             ? a.first.first < b.first.first
             : a.first.second + deep[a.first.first] <
                   b.first.second + deep[b.first.first];
}
void update(int u, int v, int x) {
  while (top[u] != top[v]) {
    insert(1, n, in[top[u]], in[u], x, 1);
    u = father[top[u]];
  }
  if (u != v) insert(1, n, in[v] + 1, in[u], x, 1);
}
int query(int u, int t) {
  int ans = deep[u] + t;
  while (1) {
    int t = ask(1, n, in[top[u]], in[u], ans, 1);
    if (t) return t;
    u = father[top[u]];
  }
}
int main() {
  n = read() + 1;
  m = read();
  for (int i = 1; i < (N << 2); i++) lazy[i] = -oo;
  for (int i = 2; i <= n; i++) {
    deep[i] = deep[father[i] = read() + 1] + 1;
    aedge(father[i], i);
  }
  dfs1(1);
  dfs2(1);
  for (int i = 1; i <= m; i++) {
    a[i].first.first = read() + 1;
    a[i].first.second = read();
    a[i].second = i;
  }
  sort(&a[1], &a[m + 1], cmp);
  for (int i = 1; i <= m; i++) {
    int t = query(a[i].first.first, a[i].first.second);
    ans[a[i].second] =
        a[i].first.second + (deep[a[i].first.first] - deep[t]) * 2;
    update(a[i].first.first, t, ans[a[i].second] - deep[a[i].first.first]);
  }
  for (int i = 1; i <= m; i++) write(ans[i]), putchar(' ');
}
