#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
const int cipher = -1e9;
template <typename T>
void chkmax(T &x, T y) {
  x = max(x, y);
}
template <typename T>
void chkmin(T &x, T y) {
  x = min(x, y);
}
template <typename T>
void read(T &x) {
  x = 0;
  int f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -f;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  x *= f;
}
template <typename T>
void write(T x) {
  if (x < 0) x = -x, putchar('-');
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
template <typename T>
void writeln(T x) {
  write(x);
  puts("");
}
struct SegmentTree {
  struct Node {
    int lc, rc;
    int tag, Max, depth;
  } a[MAXN * 2];
  int root, size, n, depth[MAXN];
  void update(int root) {
    a[root].Max = max(a[a[root].lc].Max, a[a[root].rc].Max);
    a[root].depth = max(a[a[root].lc].depth, a[a[root].rc].depth);
  }
  void build(int &root, int l, int r) {
    root = ++size;
    a[root].Max = -2e9;
    a[root].tag = cipher;
    if (l == r) {
      a[root].depth = depth[l];
      return;
    }
    int mid = (l + r) / 2;
    build(a[root].lc, l, mid);
    build(a[root].rc, mid + 1, r);
    update(root);
  }
  void init(int x, int *y) {
    n = x, size = 0;
    for (int i = 1; i <= n; i++) depth[i] = 2 * y[i];
    build(root, 1, n);
  }
  void pushdown(int root) {
    if (a[root].tag != cipher && a[root].lc) {
      a[a[root].lc].Max = a[root].tag + a[a[root].lc].depth;
      a[a[root].lc].tag = a[root].tag;
      a[a[root].rc].Max = a[root].tag + a[a[root].rc].depth;
      a[a[root].rc].tag = a[root].tag;
      a[root].tag = cipher;
    }
  }
  void modify(int root, int l, int r, int ql, int qr, int x) {
    if (l == ql && r == qr) {
      a[root].Max = x + a[root].depth;
      a[root].tag = x;
      return;
    }
    pushdown(root);
    int mid = (l + r) / 2;
    if (mid >= ql) modify(a[root].lc, l, mid, ql, min(mid, qr), x);
    if (mid + 1 <= qr) modify(a[root].rc, mid + 1, r, max(mid + 1, ql), qr, x);
    update(root);
  }
  void modify(int l, int r, int x) { modify(root, 1, n, l, r, x); }
  int query(int root, int l, int r, int ql, int qr, int x) {
    pushdown(root);
    int mid = (l + r) / 2;
    if (l == ql && r == qr) {
      if (l == r) {
        if (a[root].Max > x)
          return l;
        else
          return l - 1;
      }
      if (a[a[root].rc].Max > x)
        return query(a[root].rc, mid + 1, r, mid + 1, r, x);
      else
        return query(a[root].lc, l, mid, l, mid, x);
    }
    if (mid >= qr) return query(a[root].lc, l, mid, ql, qr, x);
    if (mid + 1 <= ql) return query(a[root].rc, mid + 1, r, ql, qr, x);
    int tans = query(a[root].rc, mid + 1, r, mid + 1, qr, x);
    if (tans == mid)
      return query(a[root].lc, l, mid, ql, mid, x);
    else
      return tans;
  }
  int query(int l, int r, int x) { return query(root, 1, n, l, r, x); }
} ST;
vector<int> a[MAXN], points[MAXN];
int y[MAXN], t[MAXN], p[MAXN], ans[MAXN], val[MAXN];
int n, m, depth[MAXN], size[MAXN], son[MAXN];
int timer, father[MAXN], dfn[MAXN], up[MAXN];
void dfs(int pos, int fa) {
  depth[pos] = depth[fa] + 1;
  size[pos] = 1, son[pos] = 0;
  for (auto x : a[pos])
    if (x != fa) {
      dfs(x, pos);
      size[pos] += size[x];
      if (size[x] > size[son[pos]]) son[pos] = x;
    }
}
void efs(int pos, int fa, int from) {
  up[pos] = from;
  father[pos] = fa;
  dfn[pos] = ++timer;
  points[from].push_back(pos);
  if (son[pos]) efs(son[pos], pos, from);
  for (auto x : a[pos])
    if (x != son[pos] && x != fa) efs(x, pos, x);
}
bool cmp(int a, int b) {
  if (t[a] + depth[y[a]] == t[b] + depth[y[b]])
    return y[a] < y[b];
  else
    return t[a] + depth[y[a]] < t[b] + depth[y[b]];
}
int main() {
  read(n), read(m);
  for (int i = 2; i <= n + 1; i++) {
    int x;
    read(x), x++;
    a[x].push_back(i);
  }
  dfs(1, 0);
  efs(1, 0, 1);
  for (int i = 1; i <= m; i++) {
    read(y[i]), y[i]++;
    read(t[i]), p[i] = i;
  }
  sort(p + 1, p + m + 1, cmp);
  static int tmp[MAXN];
  for (int i = 1; i <= n + 1; i++) tmp[dfn[i]] = depth[i];
  ST.init(n + 1, tmp);
  ST.modify(1, 1, 2e9);
  for (int i = 1; i <= m; i++) {
    int pos = y[p[i]], x = pos, res = 0;
    while (true) {
      int f = up[x];
      int tmp = ST.query(dfn[f], dfn[x], depth[pos] + t[p[i]]);
      if (tmp == dfn[f] - 1)
        res += dfn[x] - dfn[f] + 1;
      else {
        res += dfn[x] - tmp;
        break;
      }
      x = father[f];
    }
    x = pos;
    ans[p[i]] = t[p[i]] + 2 * res;
    int tres = res;
    while (tres) {
      int f = up[x];
      if (tres <= dfn[x] - dfn[f] + 1) {
        ST.modify(dfn[x] - tres + 1, dfn[x], t[p[i]] + 2 * res - depth[pos]);
        break;
      } else {
        tres -= dfn[x] - dfn[f] + 1;
        ST.modify(dfn[f], dfn[x], t[p[i]] + 2 * res - depth[pos]);
      }
      x = father[f];
    }
  }
  for (int i = 1; i <= m; i++) printf("%d ", ans[i]);
  return 0;
}
