#include <bits/stdc++.h>
using namespace std;
template <typename T>
void read(T &x) {
  x = 0;
  char ch = getchar();
  int fh = 1;
  while (ch < '0' || ch > '9') {
    if (ch == '-') fh = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  x *= fh;
}
struct Onfo {
  int nu, ne;
} a[200010 * 2];
struct Info {
  int x, t, we, an;
} v[200010];
struct seg {
  int l, r, ma, ta, de;
} t[200010 * 4];
int b[200010], num, m, n, x, so[200010], si[200010], d[200010], f[200010],
    tp[200010], bi[200010], fb[200010];
vector<int> no;
bool co(const Info &a, const Info &b) {
  if (a.t + d[a.x] != b.t + d[b.x]) return a.t + d[a.x] < b.t + d[b.x];
  return a.x < b.x;
}
bool c1(const Info &a, const Info &b) { return a.we < b.we; }
void jb(int x, int y) {
  a[++num].nu = y;
  a[num].ne = b[x];
  b[x] = num;
}
void dfs(int x, int fa, int dep) {
  si[x] = 1;
  so[x] = 0;
  f[x] = fa;
  d[x] = dep;
  for (int y = b[x]; y; y = a[y].ne) {
    if (a[y].nu != fa) {
      dfs(a[y].nu, x, dep + 1);
      si[x] += si[a[y].nu];
      if (si[a[y].nu] > si[so[x]]) so[x] = a[y].nu;
    }
  }
}
void dfs1(int x) {
  bi[x] = ++num;
  fb[num] = x;
  if (so[x] != 0) {
    tp[so[x]] = tp[x];
    dfs1(so[x]);
  }
  for (int y = b[x]; y; y = a[y].ne) {
    if (a[y].nu != f[x] && a[y].nu != so[x]) {
      tp[a[y].nu] = a[y].nu;
      dfs1(a[y].nu);
    }
  }
}
void build(int nu, int l, int r) {
  t[nu].ma = -2e9;
  t[nu].l = l;
  t[nu].r = r;
  t[nu].ta = -2e9;
  if (l != r) {
    build(nu * 2, l, (l + r) / 2);
    build(nu * 2 + 1, (l + r) / 2 + 1, r);
    t[nu].de = t[nu * 2 + 1].de;
  } else {
    t[nu].de = d[fb[l]];
  }
}
void ya(int nu) {
  if (t[nu].ta != -2e9) {
    if (t[nu].l != t[nu].r) {
      t[nu * 2].ta = t[nu].ta;
      t[nu * 2 + 1].ta = t[nu].ta;
    }
    t[nu].ma = t[nu].ta + t[nu].de * 2;
    t[nu].ta = -2e9;
  }
}
int que(int nu, int l, int r) {
  ya(nu);
  if (t[nu].l == l && t[nu].r == r) return t[nu].ma;
  int mid = (t[nu].l + t[nu].r) / 2;
  if (l > mid) return que(nu * 2 + 1, l, r);
  if (r <= mid) return que(nu * 2, l, r);
  return max(que(nu * 2, l, mid), que(nu * 2 + 1, mid + 1, r));
}
void get(int nu, int l, int r) {
  ya(nu);
  if (t[nu].l == l && t[nu].r == r) {
    no.push_back(nu);
    return;
  }
  int mid = (t[nu].l + t[nu].r) / 2;
  if (l <= mid) get(nu * 2, l, min(mid, r));
  if (r > mid) get(nu * 2 + 1, max(mid + 1, l), r);
}
int getans(int nu, int y) {
  if (t[nu].l == t[nu].r) return fb[t[nu].l];
  ya(nu * 2 + 1);
  if (t[nu * 2 + 1].ma <= y) return getans(nu * 2, y);
  return getans(nu * 2 + 1, y);
}
int get(int x, int y) {
  while (x != 0) {
    if (que(1, bi[tp[x]], bi[x]) > y) {
      no.clear();
      get(1, bi[tp[x]], bi[x]);
      for (int i = no.size() - 1; i >= 0; i--) {
        if (t[no[i]].ma > y) return getans(no[i], y);
      }
    }
    x = f[tp[x]];
  }
  return x;
}
void add(int nu, int l, int r, int x) {
  ya(nu);
  if (t[nu].l == l && t[nu].r == r) {
    t[nu].ta = x;
    return;
  }
  int mid = (t[nu].l + t[nu].r) / 2;
  if (l <= mid) add(nu * 2, l, min(mid, r), x);
  if (r > mid) add(nu * 2 + 1, max(mid + 1, l), r, x);
  ya(nu * 2);
  ya(nu * 2 + 1);
  t[nu].ma = max(t[nu * 2].ma, t[nu * 2 + 1].ma);
}
void fu(int x, int y, int z) {
  while (tp[x] != tp[y]) {
    add(1, bi[tp[x]], bi[x], z);
    x = f[tp[x]];
  }
  if (x != y) add(1, bi[y] + 1, bi[x], z);
}
int main() {
  read(n);
  read(m);
  for (int i = 1; i <= n; i++) {
    read(x);
    jb(x + 1, i + 1);
    jb(i + 1, x + 1);
  }
  n++;
  dfs(1, 0, 1);
  num = 0;
  tp[1] = 1;
  dfs1(1);
  build(1, 1, n);
  add(1, 1, 1, 2e9);
  for (int i = 1; i <= m; i++) {
    read(v[i].x);
    read(v[i].t);
    v[i].x++;
    v[i].we = i;
  }
  sort(v + 1, v + m + 1, co);
  for (int i = 1; i <= m; i++) {
    v[i].an = get(v[i].x, v[i].t + d[v[i].x]);
    fu(v[i].x, v[i].an, v[i].t + d[v[i].x] - d[v[i].an] * 2);
  }
  sort(v + 1, v + m + 1, c1);
  for (int i = 1; i <= m; i++)
    printf("%d ", v[i].t + d[v[i].x] * 2 - d[v[i].an] * 2);
  puts("");
  return 0;
}
