//tm标记维护错了
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define ls (x<<1)
#define rs (x<<1|1)
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=5e5+100;
const int inf=1e9;
int n,m,h[N],cnt,d[N],mx[N],f[N],sz[N],top[N],L[N],R[N],tim,id[N],son[N],ans[N];
struct seg
{
  int d,mx,l;
  il seg(){mx=l=-inf;}
}t[N<<2];
struct Edge{int to,nxt;}e[N<<1];
struct dat
{
	int p,t,id;
	il bool operator < (const dat &o) const
		{
			if(d[p]+t==d[o.p]+o.t) return p<o.p;
			else return d[p]+t<d[o.p]+o.t;
		}
}a[N];
il void add(re int u,re int v)
{
	e[++cnt]=(Edge){v,h[u]};h[u]=cnt;
	e[++cnt]=(Edge){u,h[v]};h[v]=cnt;
}
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void dfs1(re int u,re int fa)
{
  d[u]=d[fa]+1;f[u]=fa;sz[u]=1;
  for(re int i=h[u];i+1;i=e[i].nxt)
    {
      re int v=e[i].to;
      if(v==fa) continue;
      dfs1(v,u);
      sz[u]+=sz[v];
      if(sz[son[u]]<sz[v]) son[u]=v;
    }
}
il void dfs2(re int u,re int up)
{
  top[u]=up;L[u]=++tim;id[tim]=u;
  if(son[u]) dfs2(son[u],up);
  for(re int i=h[u];i+1;i=e[i].nxt)
    {
      re int v=e[i].to;
      if(v==f[u]||v==son[u]) continue;
      dfs2(v,v);
    }
  R[u]=tim;
}
il void cover(re int x,re int w)
{
  t[x].mx=max(t[x].mx,t[x].d+w);t[x].l=max(t[x].l,w);
}
il void Pushdown(re int x)
{
  cover(ls,t[x].l);cover(rs,t[x].l);
  t[x].l=-inf;
}
il void upd(re int x)
{
	t[x].mx=max(t[ls].mx,t[rs].mx);
}
il void Build(re int x,re int l,re int r)
{
  if(l==r) {t[x].d=d[id[l]]<<1;return;}
  re int mid=l+r>>1;
  Build(ls,l,mid);Build(rs,mid+1,r);
  t[x].d=max(t[ls].d,t[rs].d);
}
il void Modify(re int x,re int l,re int r,re int ql,re int qr,re int w)
{
  if(ql<=l&&r<=qr) {cover(x,w);return;}
	 if(t[x].l!=-inf)	Pushdown(x);
  re int mid=l+r>>1;
  if(ql<=mid) Modify(ls,l,mid,ql,qr,w);
  if(qr>mid) Modify(rs,mid+1,r,ql,qr,w);
  upd(x);
}
il int Query(re int x,re int l,re int r,re int ql,re int qr)
{
  if(ql<=l&&r<=qr) return t[x].mx;
  if(t[x].l!=-inf)	Pushdown(x);
  re int mid=l+r>>1,mx=-inf;
  if(ql<=mid) mx=max(mx,Query(ls,l,mid,ql,qr));
  if(qr>mid) mx=max(mx,Query(rs,mid+1,r,ql,qr));
  upd(x);
  return mx;
}
int main()
{
 // freopen("message.in","r",stdin);
 // freopen("message.out","w",stdout);
	memset(h,-1,sizeof(h));
  n=gi()+1;m=gi();
	fp(i,2,n) add(gi()+1,i);
	dfs1(1,0);dfs2(1,1);
	Build(1,1,n);
	fp(i,1,m) a[i].p=gi()+1,a[i].t=gi(),a[i].id=i;
	sort(a+1,a+1+m);
//	fp(i,1,n) printf("%d ",top[i]);puts("");
	fp(i,1,m)
	{
	  re int u=a[i].p,p=a[i].p,gu=1;
	  while(u)
	    {
	      if(Query(1,1,n,L[top[u]],L[u])<=a[i].t+d[p]) {u=f[top[u]];continue;}
	      re int l=L[top[u]],r=L[u];
	      while(l<=r)
		{
		  re int mid=l+r>>1;
		  if(Query(1,1,n,mid,L[u])>a[i].t+d[p]) gu=id[mid],l=mid+1;
		  else r=mid-1;
		}
	      break;
	    }
		//	printf("!!!%d %d %d %d\n",gu,Query(1,1,n,L[p],L[p]),a[i].t+d[p],Query(1,1,n,L[top[p]],L[p]));
		ans[a[i].id]=a[i].t+(d[p]-d[gu]<<1);
	    u=a[i].p;
	    while(d[u]>=d[gu])
	      {
				  Modify(1,1,n,L[top[u]],L[u],ans[a[i].id]-d[p]);
					u=f[top[u]];
	      }
	}
	fp(i,1,m) printf("%d\n",ans[i]);
  return 0;
}


#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define ls (x<<1)
#define rs (x<<1|1)
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=5e5+100;
const int inf=1e9;
int n,m,h[N],cnt,d[N],mx[N],f[N],sz[N],top[N],L[N],R[N],tim,id[N],son[N],ans[N];
struct seg
{
  int d,mx,l;
  il seg(){mx=l=-inf;}
}t[N<<2];
struct Edge{int to,nxt;}e[N<<1];
struct dat
{
	int p,t,id;
	il bool operator < (const dat &o) const
		{
			if(d[p]+t==d[o.p]+o.t) return p<o.p;
			else return d[p]+t<d[o.p]+o.t;
		}
}a[N];
il void add(re int u,re int v)
{
	e[++cnt]=(Edge){v,h[u]};h[u]=cnt;
	e[++cnt]=(Edge){u,h[v]};h[v]=cnt;
}
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void dfs1(re int u,re int fa)
{
  d[u]=d[fa]+1;f[u]=fa;sz[u]=1;
  for(re int i=h[u];i+1;i=e[i].nxt)
    {
      re int v=e[i].to;
      if(v==fa) continue;
      dfs1(v,u);
      sz[u]+=sz[v];
      if(sz[son[u]]<sz[v]) son[u]=v;
    }
}
il void dfs2(re int u,re int up)
{
  top[u]=up;L[u]=++tim;id[tim]=u;
  if(son[u]) dfs2(son[u],up);
  for(re int i=h[u];i+1;i=e[i].nxt)
    {
      re int v=e[i].to;
      if(v==f[u]||v==son[u]) continue;
      dfs2(v,v);
    }
  R[u]=tim;
}
il void cover(re int x,re int w)
{
  t[x].mx=max(t[x].mx,t[x].d+w);t[x].l=max(t[x].l,w);
}
il void Pushdown(re int x)
{
  cover(ls,t[x].l);cover(rs,t[x].l);
  t[x].l=-inf;
}
il void upd(re int x)
{
	t[x].mx=max(t[ls].mx,t[rs].mx);
}
il void Build(re int x,re int l,re int r)
{
  if(l==r) {t[x].d=d[id[l]]<<1;return;}
  re int mid=l+r>>1;
  Build(ls,l,mid);Build(rs,mid+1,r);
  t[x].d=max(t[ls].d,t[rs].d);
}
il void Modify(re int x,re int l,re int r,re int ql,re int qr,re int w)
{
  if(ql<=l&&r<=qr) {cover(x,w);return;}
	 if(t[x].l!=-inf)	Pushdown(x);
  re int mid=l+r>>1;
  if(ql<=mid) Modify(ls,l,mid,ql,qr,w);
  if(qr>mid) Modify(rs,mid+1,r,ql,qr,w);
  upd(x);
}
il int Query(re int x,re int l,re int r,re int ql,re int qr)
{
  if(ql<=l&&r<=qr) return t[x].mx;
  if(t[x].l!=-inf)	Pushdown(x);
  re int mid=l+r>>1,mx=-inf;
  if(ql<=mid) mx=max(mx,Query(ls,l,mid,ql,qr));
  if(qr>mid) mx=max(mx,Query(rs,mid+1,r,ql,qr));
  upd(x);
  return mx;
}
int main()
{
 // freopen("message.in","r",stdin);
 // freopen("message.out","w",stdout);
	memset(h,-1,sizeof(h));
  n=gi()+1;m=gi();
	fp(i,2,n) add(gi()+1,i);
	dfs1(1,0);dfs2(1,1);
	Build(1,1,n);
	fp(i,1,m) a[i].p=gi()+1,a[i].t=gi(),a[i].id=i;
	sort(a+1,a+1+m);
//	fp(i,1,n) printf("%d ",top[i]);puts("");
	fp(i,1,m)
	{
	  re int u=a[i].p,p=a[i].p,gu=1;
	  while(u)
	    {
	      if(Query(1,1,n,L[top[u]],L[u])<=a[i].t+d[p]) {u=f[top[u]];continue;}
	      re int l=L[top[u]],r=L[u];
	      while(l<=r)
		{
		  re int mid=l+r>>1;
		  if(Query(1,1,n,mid,L[u])>a[i].t+d[p]) gu=id[mid],l=mid+1;
		  else r=mid-1;
		}
	      break;
	    }
		//	printf("!!!%d %d %d %d\n",gu,Query(1,1,n,L[p],L[p]),a[i].t+d[p],Query(1,1,n,L[top[p]],L[p]));
		ans[a[i].id]=a[i].t+(d[p]-d[gu]<<1);
	    u=a[i].p;
	    while(d[u]>=d[gu])
	      {
				  Modify(1,1,n,L[top[u]],L[u],ans[a[i].id]-d[p]);
					u=f[top[u]];
	      }
	}
	fp(i,1,m) printf("%d\n",ans[i]);
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x = 0,f = 1;char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9'){x = x*10+ch-'0';ch = getchar();}
	return x*f;
}
void write(int x){
	if(x > 9) write(x/10);
	putchar(x%10+'0');
}

const int N = 200005,inf = 1e9;
int a[N],t[N],id[N],fa[N],dep[N],num[N],son[N],q[N],dfn[N];
int top[N],ans[N],n,m,cnt = 0,fd;
struct tree{ int mx,lazy; }tr[N<<2];
bool cmp(int x,int y){
	if(t[x]+dep[a[x]] != t[y]+dep[a[y]])
		return t[x]+dep[a[x]] < t[y]+dep[a[y]];
	return a[x] < a[y];
}
inline void pushup(int x){ tr[x].mx = max(tr[x<<1].mx,tr[x<<1|1].mx); }
inline void pushdown(int x,int l,int mid,int r){
	if(tr[x].lazy < -inf) return;
	tr[x<<1].lazy = tr[x<<1|1].lazy = tr[x].lazy;
	tr[x<<1].mx = mid*2+tr[x].lazy;
	tr[x<<1|1].mx = r*2+tr[x].lazy;
	tr[x].lazy = -inf-1;
}
void modify(int now,int l,int r,int x,int y,int z){
	if(x <= l && r <= y){
		tr[now].lazy = z; tr[now].mx = r*2+z;
		return;
	}
	int mid = (l+r)>>1;
	pushdown(now,l,mid,r);
	if(x <= mid) modify(now<<1,l,mid,x,y,z);
	if(y > mid) modify(now<<1|1,mid+1,r,x,y,z);
	pushup(now);
}
void query(int now,int l,int r,int x,int y,int z){
	if(tr[now].mx <= z) return;
	if(l == r){fd = q[l];return;}
	int mid = (l+r)>>1;
	pushdown(now,l,mid,r);
	if(fd == -1 && y > mid) query(now<<1|1,mid+1,r,x,y,z);
	if(fd == -1 && x <= mid) query(now<<1,l,mid,x,y,z);
	pushup(now);
}
int work(int x,int t){
	int y = x;
	while(1){
		fd = -1;
		query(1,0,n,dfn[top[y]],dfn[y],t+dfn[y]);
		if(fd >= 0){
			t += dep[y]-dep[fd];
			y = fd;
			break;
		}
		if(!y) break;
		t += dep[y]-dep[fa[top[y]]];
		y = fa[top[y]];
	}
	int z = t+dep[x]-dep[y];
	while(1){
		if(top[x] == top[y]){
			if(x != y) modify(1,0,n,dfn[y]+1,dfn[x],t-dfn[y]);
			break;
		}
		modify(1,0,n,dfn[top[x]],dfn[x],dep[x]-dep[y]+t-dfn[x]);
		x = fa[top[x]];
	}
	return z;
}

int main(){
	n = read(); m = read();
	for(int i = 1;i <= n;++i){
		fa[i] = read();
		dep[i] = dep[fa[i]]+1;
		num[i] = 1;
	}
	for(int i = n;i;i--){
		if(num[i] > num[son[fa[i]]]) son[fa[i]] = i;
		if(fa[i]) num[fa[i]] += num[i];
	}
	for(int i = son[0];i;i = son[i]) q[dfn[i] = ++cnt] = i;
	for(int i = 0;i <= n;++i)
		if(!dfn[i])
			for(int j = i;j;j = son[j])
				top[q[dfn[j] = ++cnt] = j] = i;
	for(int i = 1;i <= m;++i) a[i] = read(),t[i] = read();
	for(int i = 1;i <= m;++i) id[i] = i;
	sort(id+1,id+m+1,cmp);
	tr[1].mx = tr[1].lazy = -inf;
	for(int i = 1;i <= m;++i)
		ans[id[i]] = work(a[id[i]],t[id[i]]);
	for(int i = 1;i <= m;++i) write(ans[i]),putchar(' ');
	puts("");
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#include<cmath>
#include<string>

#define ls (t<<1)
#define rs ((t<<1)+1)
#define mid ((l+r)>>1)
#define fi first
#define se second
#define mk make_pair
#define pb push_back

#define N 200005
#define M 200005
#define seed 23333
#define Mo 998244353

using namespace std;
const int inf=(int)(1e9)+N*10;
int i,j,m,n,p,k,a[N],fa[N],st[N],deep[N],son[N],top[N],size[N],tot,Que[N],ma[N];
vector<int>v[N];
struct Node{
		int x,t;
}Q[N];
struct gao{
		int x,y,id;
}A[N];
void dfs(int x)
{
		int i;
		for (i=0;i<(int)v[x].size();++i)
		{
				int p=v[x][i];
				deep[p]=deep[x]+1;
				dfs(p);
				size[x]+=size[p];
				if (!son[x]||size[son[x]]<size[p]) son[x]=p;
		}
		size[x]++;
}
void Dfs(int x,int tp)
{
		int i;
		st[x]=++tot; Que[tot]=x;
		top[x]=tp;
		if (son[x]) Dfs(son[x],tp);
		for (i=0;i<(int)v[x].size();++i)
		{
				int p=v[x][i];
				if (p==son[x]) continue;
				Dfs(p,p);
		}
}
inline int cmp(gao a,gao b)
{
		if (a.x!=b.x) return a.x<b.x;
		return a.y<b.y;
}
struct Tre{
		int sum,add;
}tree[N*4];
void down(int t,int l,int r)
{
		tree[ls].add=max(tree[ls].add,tree[t].add);
		tree[ls].sum=max(tree[ls].sum,tree[ls].add+2*deep[Que[mid]]);
		tree[rs].add=max(tree[rs].add,tree[t].add);
		tree[rs].sum=max(tree[rs].sum,tree[rs].add+2*deep[Que[r]]);
}
void build_tree(int l,int r,int t)
{
		tree[t].add=-inf;
		if (l==r)
		{
				if (l==1) tree[t].sum=inf;
				else tree[t].sum=-inf;
		}
		else
		{
				build_tree(l,mid,ls);
				build_tree(mid+1,r,rs);
				tree[t].sum=max(tree[ls].sum,tree[rs].sum);
		}
}
int getMax(int ll,int rr,int l,int r,int t)
{
		if (ll<=l&&r<=rr) return tree[t].sum;
		else
		{
				down(t,l,r);
				int S=-1000000;
				if (ll<=mid) S=max(S,getMax(ll,rr,l,mid,ls));
				if (rr>mid)  S=max(S,getMax(ll,rr,mid+1,r,rs));
				return S;
		}
}
int Find(int ll,int rr,int c,int l,int r,int t)
{
		if (tree[t].sum<c) return 0;
		if (l==r) return r;
		else if (ll<=l&&r<=rr)
		{
				down(t,l,r);
				if (tree[rs].sum>=c) return Find(ll,rr,c,mid+1,r,rs);
				return Find(ll,rr,c,l,mid,ls);
		}
		else
		{
				down(t,l,r);
				if (rr>mid)
				{
					 int ID=Find(ll,rr,c,mid+1,r,rs);
					 if (ID) return ID;
				}
				if (ll<=mid)
				{
					 int ID=Find(ll,rr,c,l,mid,ls);
					 if (ID) return ID;
				}
				return 0;
		}
}
void ins(int ll,int rr,int c,int l,int r,int t)
{
		if (ll<=l&&r<=rr)
		{
			tree[t].add=max(tree[t].add,c);
			tree[t].sum=max(tree[t].sum,tree[t].add+2*deep[Que[r]]);
		}
		else
		{
			down(t,l,r);
			if (ll<=mid) ins(ll,rr,c,l,mid,ls);
			if (rr>mid)  ins(ll,rr,c,mid+1,r,rs);
			tree[t].sum=max(tree[ls].sum,tree[rs].sum);
		}
}
int main()
{
	  scanf("%d%d",&n,&m);
	  for (i=1;i<=n;++i) scanf("%d",&fa[i]),v[fa[i]].pb(i);
	  dfs(0);
	  Dfs(0,0);
	  for (i=1;i<=m;++i) scanf("%d%d",&Q[i].x,&Q[i].t),A[i]=(gao){Q[i].t+deep[Q[i].x],Q[i].x,i};
	  sort(A+1,A+m+1,cmp);
	  build_tree(1,tot,1);
	  for (i=1;i<=m;++i)
	  {
	  		int now=Q[A[i].id].x,ti=Q[A[i].id].t,guan=ti+deep[now],x=now,ID;
	  			for (;;)
	  		{
	  				int ans=getMax(st[top[x]],st[x],1,tot,1);
	  				if (ans>=guan)
					{
						ID=Que[Find(st[top[x]],st[x],guan,1,tot,1)];
						break;
					}
					x=fa[top[x]];
	  		}
	  		ma[A[i].id]=ID;
	  		int goal=ti+deep[now]-deep[ID]-1-deep[ID];
	  		for (;top[now]!=top[ID];)
	  		{
	  				ins(st[top[now]],st[now],goal,1,tot,1);
	  				now=fa[top[now]];
	  		}
	  		ins(st[ID],st[now],goal,1,tot,1);
	  }
	  for (i=1;i<=m;++i) printf("%d ",Q[i].t+2*(deep[Q[i].x]-deep[ma[i]]));
}


#include <algorithm>
#include <iostream>
#include <ios>
#include <functional>
#include <map>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cassert>
uint32_t readu32() { int c; while ((c = getchar()) < '0'); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } uint64_t readu64() { int c; while ((c = getchar()) < '0'); uint64_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } int32_t read32() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int32_t)n : n; } int64_t read64() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint64_t n = c & 15; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int64_t)n : n; } template<typename F, F f> struct no_arg_call { template<typename T> struct stupid_compiler { typedef T type; }; operator typename stupid_compiler<decltype(f())>::type() { return f(); } }; no_arg_call<decltype(&readu32), readu32> IU; no_arg_call<decltype(&read32), read32> II; no_arg_call<decltype(&readu64), readu64> IUL; no_arg_call<decltype(&read64), read64> IL;

#define N 200002

using namespace std;

struct node;

struct seg {
    int dir;
    int top;
    int time;
    int prev;
    int ini;

    int topNow(int bottom, int t) {
        if (dir == 0)
            return top;
        int dt = t - time;
        if (dir == 1)
            return bottom + dt;
        return top - dt;
    }
};

struct path {
    vector<int> p;
    map<int, seg> u;
};

struct node {
    int par;
    path* p;
    int ip;
    vector<int> ch;
};

int w[N];
path pa[N];
node v[N];

int out[N];

void calcw(int u) {
    int s = 1;
    for (int x : v[u].ch) {
        calcw(x);
        s += w[x];
    }
    w[u] = s;
}

void hld(int u, path* hp = nullptr) {
    if (!hp)
        hp = pa + u;

    int wmax = 0, vmax;
    for (int x : v[u].ch) {
        if (w[x] > wmax) {
            wmax = w[x];
            vmax = x;
        }
    }
    for (int x : v[u].ch) {
        if (x == vmax)
            hld(x, hp);
        else
            hld(x);
    }
    v[u].ip = (int) hp->p.size();
    hp->p.push_back(u);
    v[u].p = hp;
}

enum class evt {
    desc,

    collide = 2,

    init = 4,
    asc,
};

struct event {
    evt type;
    int time;
    int mid;
    int ini;
    node* loc;
    int last;

    bool operator<(const event& o) const {
        if (time != o.time)
            return time > o.time;
        if ((int)type / 2 != (int)o.type / 2)
            return type > o.type;
        return ini > o.ini;
    }
};

void addcol(path& p, map<int, seg>::iterator it, priority_queue<event>& q) {
    auto nex = next(it);
    if (nex == p.u.end()) return;
    event e;
    e.time = it->second.time + (nex->first - it->first);
    e.loc = v + p.p[it->first];
    e.type = evt::collide;
    q.push(e);
}

void down(int x, int t, priority_queue<event>& q) {
    auto it = v[x].p->u.find(v[x].ip);
    auto& s = it->second;
    if (s.dir == 1) {
        s.top = s.topNow(it->first, t) - 1;
    }
    s.dir = -1;
    s.time = t;
    event e;
    e.time = t + (s.top - it->first + 1);
    e.type = evt::desc;
    e.loc = v + x;
    q.push(e);
}

bool try_asc(int ini, node* x, int t, int pre, priority_queue<event>& q) {
    auto& m = x->p->u;
    auto it = m.upper_bound(x->ip);
    if (it != m.begin()) {
        --it;
        int tp = it->second.topNow(it->first, t);
        if (tp > x->ip)
            return false;
        if (tp == x->ip) {
            if (ini > it->second.ini)
                return false;
            down(x->p->p[it->first], t, q);
        }
    }
    seg s;
    s.dir = 1;
    s.time = t;
    s.prev = pre;
    s.ini = ini;
    auto it2 = m.emplace(x->ip, s).first;
    addcol(*x->p, it2, q);
    if (it2 != m.begin())
        addcol(*x->p, --it2, q);
    event e;
    e.type = evt::asc;
    e.ini = ini;
    e.loc = x;
    e.time = t + (x->p->p.size() - x->ip);
    q.push(e);
    return true;
}

int main()
{
    ios_base::sync_with_stdio(0);

    int n = IU, m = IU;
    for (int i = 1; i <= n; i++) {
        int x = IU;
        v[i].par = x;
        v[x].ch.push_back(i);
    }
    calcw(0);
    hld(0);
    priority_queue<event> pq;
    for (int i = 0; i < m; i++ ) {
        event e;
        e.type = evt::init;
        e.loc = v + IU;
        e.time = IU;
        e.mid = i;
        pq.push(e);
    }
    pa[0].u.emplace(v[0].ip, seg());

    while (!pq.empty()) {
        event e = pq.top();
        pq.pop();
        switch (e.type) {
        case evt::init:
            if (!try_asc(e.loc - v, e.loc, e.time, ~e.mid, pq))
                out[e.mid] = e.time;
            break;

        case evt::asc:
        case evt::collide:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            if (it == m.end()) break;
            seg& s = it->second;
            if (s.dir != 1) break;
            int tn = s.topNow(it->first, e.time);
            if (tn >= e.loc->p->p.size()) { //ascend
                s.top = (int) e.loc->p->p.size() - 1;
                assert(tn == s.top + 1);
                if (try_asc(s.ini, v + v[e.loc->p->p.back()].par, e.time, e.loc - v, pq)) {
                    s.dir = 0;
                } else {
                    down(e.loc - v, e.time, pq);
                }
            } else { //collision?
                auto nx = next(it);
                if (nx != m.end() && tn >= nx->first) {
                    assert(tn == nx->first);
                    down(e.loc - v, e.time, pq);
                }
            }

            break;
        }
        case evt::desc:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            seg& s = it->second;
            int prev = s.prev;
            auto after = m.erase(it);
            if (after != m.begin()) {
                --after;
                addcol(*e.loc->p, after, pq);
            }
            if (prev < 0) {
                out[~prev] = e.time;
            } else {
                down(prev, e.time, pq);
            }
            break;
        }
        }
    }

    for (int i = 0; i < m; i++)
        printf("%d ", out[i]);

    return 0;
}

/*
unclear case:
3 2
0 1 1
2 1
1 2

2 2
2 0
1 1
2 2

*/


#include <algorithm>
#include <iostream>
#include <ios>
#include <functional>
#include <map>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cassert>
uint32_t readu32() { int c; while ((c = getchar()) < '0'); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } uint64_t readu64() { int c; while ((c = getchar()) < '0'); uint64_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } int32_t read32() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int32_t)n : n; } int64_t read64() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint64_t n = c & 15; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int64_t)n : n; } template<typename F, F f> struct no_arg_call { template<typename T> struct stupid_compiler { typedef T type; }; operator typename stupid_compiler<decltype(f())>::type() { return f(); } }; no_arg_call<decltype(&readu32), readu32> IU; no_arg_call<decltype(&read32), read32> II; no_arg_call<decltype(&readu64), readu64> IUL; no_arg_call<decltype(&read64), read64> IL;

#define N 200002

using namespace std;

struct node;

struct seg {
    int dir;
    int top;
    int time;
    int prev;
    int ini;

    int topNow(int bottom, int t) {
        if (dir == 0)
            return top;
        int dt = t - time;
        if (dir == 1)
            return bottom + dt;
        return top - dt;
    }
};

struct path {
    vector<int> p;
    map<int, seg> u;
};

struct node {
    int par;
    path* p;
    int ip;
    vector<int> ch;
};

int w[N];
path pa[N];
node v[N];

int out[N];

void calcw(int u) {
    int s = 1;
    for (int x : v[u].ch) {
        calcw(x);
        s += w[x];
    }
    w[u] = s;
}

void hld(int u, path* hp = nullptr) {
    if (!hp)
        hp = pa + u;

    int wmax = 0, vmax;
    for (int x : v[u].ch) {
        if (w[x] > wmax) {
            wmax = w[x];
            vmax = x;
        }
    }
    for (int x : v[u].ch) {
        if (x == vmax)
            hld(x, hp);
        else
            hld(x);
    }
    v[u].ip = (int) hp->p.size();
    hp->p.push_back(u);
    v[u].p = hp;
}

enum class evt {
    desc,

    collide = 2,

    init = 4,
    asc,
};

struct event {
    evt type;
    int time;
    int mid;
    int ini;
    node* loc;
    int last;

    bool operator<(const event& o) const {
        if (time != o.time)
            return time > o.time;
        if ((int)type / 2 != (int)o.type / 2)
            return type > o.type;
        return ini > o.ini;
    }
};

void addcol(path& p, map<int, seg>::iterator it, priority_queue<event>& q) {
    auto nex = next(it);
    if (nex == p.u.end()) return;
    event e;
    e.time = it->second.time + (nex->first - it->first);
    e.loc = v + p.p[it->first];
    e.type = evt::collide;
    q.push(e);
}

void down(int x, int t, priority_queue<event>& q) {
    auto it = v[x].p->u.find(v[x].ip);
    auto& s = it->second;
    if (s.dir == 1) {
        s.top = s.topNow(it->first, t) - 1;
    }
    s.dir = -1;
    s.time = t;
    event e;
    e.time = t + (s.top - it->first + 1);
    e.type = evt::desc;
    e.loc = v + x;
    q.push(e);
}

bool try_asc(int ini, node* x, int t, int pre, priority_queue<event>& q) {
    auto& m = x->p->u;
    auto it = m.upper_bound(x->ip);
    if (it != m.begin()) {
        --it;
        int tp = it->second.topNow(it->first, t);
        if (tp > x->ip)
            return false;
        if (tp == x->ip) {
            if (it->second.dir != 1 || ini > it->second.ini)
                return false;
            down(x->p->p[it->first], t, q);
        }
    }
    seg s;
    s.dir = 1;
    s.time = t;
    s.prev = pre;
    s.ini = ini;
    auto it2 = m.emplace(x->ip, s).first;
    addcol(*x->p, it2, q);
    if (it2 != m.begin())
        addcol(*x->p, --it2, q);
    event e;
    e.type = evt::asc;
    e.ini = ini;
    e.loc = x;
    e.time = t + (x->p->p.size() - x->ip);
    q.push(e);
    return true;
}

int main()
{
    ios_base::sync_with_stdio(0);

    int n = IU, m = IU;
    for (int i = 1; i <= n; i++) {
        int x = IU;
        v[i].par = x;
        v[x].ch.push_back(i);
    }
    calcw(0);
    hld(0);
    priority_queue<event> pq;
    for (int i = 0; i < m; i++ ) {
        event e;
        e.type = evt::init;
        e.loc = v + IU;
        e.time = IU;
        e.mid = i;
        pq.push(e);
    }
    seg root;
    root.top = v[0].ip;
    root.dir = 0;
    pa[0].u.emplace(v[0].ip, root);

    while (!pq.empty()) {
        event e = pq.top();
        pq.pop();
        switch (e.type) {
        case evt::init:
            if (!try_asc(e.loc - v, e.loc, e.time, ~e.mid, pq))
                out[e.mid] = e.time;
            break;

        case evt::asc:
        case evt::collide:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            if (it == m.end()) break;
            seg& s = it->second;
            if (s.dir != 1) break;
            int tn = s.topNow(it->first, e.time);
            if (tn >= e.loc->p->p.size()) { //ascend
                s.top = (int) e.loc->p->p.size() - 1;
                assert(tn == s.top + 1);
                if (try_asc(s.ini, v + v[e.loc->p->p.back()].par, e.time, e.loc - v, pq)) {
                    s.dir = 0;
                } else {
                    down(e.loc - v, e.time, pq);
                }
            } else { //collision?
                auto nx = next(it);
                if (nx != m.end() && tn >= nx->first) {
                    assert(tn == nx->first);
                    down(e.loc - v, e.time, pq);
                }
            }

            break;
        }
        case evt::desc:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            seg& s = it->second;
            int prev = s.prev;
            auto after = m.erase(it);
            if (after != m.begin()) {
                --after;
                addcol(*e.loc->p, after, pq);
            }
            if (prev < 0) {
                out[~prev] = e.time;
            } else {
                down(prev, e.time, pq);
            }
            break;
        }
        }
    }

    for (int i = 0; i < m; i++)
        printf("%d ", out[i]);

    return 0;
}

/*
unclear case:
3 2
0 1 1
2 1
1 2

2 2
2 0
1 1
2 2

*/


#include <algorithm>
#include <iostream>
#include <ios>
#include <functional>
#include <map>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
#include <stdio.h>
#include <queue>
#include <cassert>
uint32_t readu32() { int c; while ((c = getchar()) < '0'); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } uint64_t readu64() { int c; while ((c = getchar()) < '0'); uint64_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return n; } int32_t read32() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint32_t n = c & 15U; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int32_t)n : n; } int64_t read64() { int c; while ((c = getchar()) < '-'); bool neg = c == '-'; if (neg) c = getchar(); uint64_t n = c & 15; while ((c = getchar()) >= '0') n = n * 10 + (c & 15U); return neg ? -(int64_t)n : n; } template<typename F, F f> struct no_arg_call { template<typename T> struct stupid_compiler { typedef T type; }; operator typename stupid_compiler<decltype(f())>::type() { return f(); } }; no_arg_call<decltype(&readu32), readu32> IU; no_arg_call<decltype(&read32), read32> II; no_arg_call<decltype(&readu64), readu64> IUL; no_arg_call<decltype(&read64), read64> IL;

#define N 200002

using namespace std;

struct node;

struct seg {
    int dir;
    int top;
    int time;
    int prev;
    int ini;

    int topNow(int bottom, int t) {
        if (dir == 0)
            return top;
        int dt = t - time;
        if (dir == 1)
            return bottom + dt;
        return top - dt;
    }
};

struct path {
    vector<int> p;
    map<int, seg> u;
};

struct node {
    int par;
    path* p;
    int ip;
    vector<int> ch;
};

int w[N];
path pa[N];
node v[N];

int out[N];

void calcw(int u) {
    int s = 1;
    for (int x : v[u].ch) {
        calcw(x);
        s += w[x];
    }
    w[u] = s;
}

void hld(int u, path* hp = nullptr) {
    if (!hp)
        hp = pa + u;

    int wmax = 0, vmax;
    for (int x : v[u].ch) {
        if (w[x] > wmax) {
            wmax = w[x];
            vmax = x;
        }
    }
    for (int x : v[u].ch) {
        if (x == vmax)
            hld(x, hp);
        else
            hld(x);
    }
    v[u].ip = (int) hp->p.size();
    hp->p.push_back(u);
    v[u].p = hp;
}

enum class evt {
    desc,

    collide = 2,

    init = 4,
    asc,
};

struct event {
    evt type;
    int time;
    int mid;
    int ini;
    node* loc;
    int last;

    bool operator<(const event& o) const {
        if (time != o.time)
            return time > o.time;
        if ((int)type / 2 != (int)o.type / 2)
            return type > o.type;
        return ini > o.ini;
    }
};

void addcol(path& p, map<int, seg>::iterator it, priority_queue<event>& q) {
    auto nex = next(it);
    if (nex == p.u.end()) return;
    event e;
    e.time = it->second.time + (nex->first - it->first);
    e.loc = v + p.p[it->first];
    e.type = evt::collide;
    q.push(e);
}

void down(int x, int t, priority_queue<event>& q) {
    auto it = v[x].p->u.find(v[x].ip);
    auto& s = it->second;
    if (s.dir == 1) {
        s.top = s.topNow(it->first, t) - 1;
    }
    s.dir = -1;
    s.time = t;
    event e;
    e.time = t + (s.top - it->first + 1);
    e.type = evt::desc;
    e.loc = v + x;
    q.push(e);
}

bool try_asc(int ini, node* x, int t, int pre, priority_queue<event>& q) {
    auto& m = x->p->u;
    auto it = m.upper_bound(x->ip);
    if (it != m.begin()) {
        --it;
        int tp = it->second.topNow(it->first, t);
        if (tp > x->ip)
            return false;
        if (tp == x->ip) {
            if (ini > it->second.ini)
                return false;
            down(x->p->p[it->first], t, q);
        }
    }
    seg s;
    s.dir = 1;
    s.time = t;
    s.prev = pre;
    s.ini = ini;
    auto it2 = m.emplace(x->ip, s).first;
    addcol(*x->p, it2, q);
    if (it2 != m.begin())
        addcol(*x->p, --it2, q);
    event e;
    e.type = evt::asc;
    e.ini = ini;
    e.loc = x;
    e.time = t + (x->p->p.size() - x->ip);
    q.push(e);
    return true;
}

int main()
{
    ios_base::sync_with_stdio(0);

    int n = IU, m = IU;
    for (int i = 1; i <= n; i++) {
        int x = IU;
        v[i].par = x;
        v[x].ch.push_back(i);
    }
    calcw(0);
    hld(0);
    priority_queue<event> pq;
    for (int i = 0; i < m; i++ ) {
        event e;
        e.type = evt::init;
        e.loc = v + IU;
        e.time = IU;
        e.mid = i;
        pq.push(e);
    }
    seg root;
    root.top = v[0].ip;
    root.dir = 0;
    pa[0].u.emplace(v[0].ip, root);

    while (!pq.empty()) {
        event e = pq.top();
        pq.pop();
        switch (e.type) {
        case evt::init:
            if (!try_asc(e.loc - v, e.loc, e.time, ~e.mid, pq))
                out[e.mid] = e.time;
            break;

        case evt::asc:
        case evt::collide:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            if (it == m.end()) break;
            seg& s = it->second;
            if (s.dir != 1) break;
            int tn = s.topNow(it->first, e.time);
            if (tn >= e.loc->p->p.size()) { //ascend
                s.top = (int) e.loc->p->p.size() - 1;
                assert(tn == s.top + 1);
                if (try_asc(s.ini, v + v[e.loc->p->p.back()].par, e.time, e.loc - v, pq)) {
                    s.dir = 0;
                } else {
                    down(e.loc - v, e.time, pq);
                }
            } else { //collision?
                auto nx = next(it);
                if (nx != m.end() && tn >= nx->first) {
                    assert(tn == nx->first);
                    down(e.loc - v, e.time, pq);
                }
            }

            break;
        }
        case evt::desc:
        {
            auto& m = e.loc->p->u;
            auto it = m.find(e.loc->ip);
            seg& s = it->second;
            int prev = s.prev;
            auto after = m.erase(it);
            if (after != m.begin()) {
                --after;
                addcol(*e.loc->p, after, pq);
            }
            if (prev < 0) {
                out[~prev] = e.time;
            } else {
                down(prev, e.time, pq);
            }
            break;
        }
        }
    }

    for (int i = 0; i < m; i++)
        printf("%d ", out[i]);

    return 0;
}

/*
unclear case:
3 2
0 1 1
2 1
1 2

2 2
2 0
1 1
2 2

*/


#include <algorithm>
#include <cstdio>
const int N=200005,inf=2000000000;
int a[N],t[N],id[N],fa[N],dep[N],num[N],son[N],q[N],dfn[N],
	top[N],mx[N<<2],tag[N<<2],ans[N],n,m,cnt=0,fd;
bool cmp(int x,int y){
	if (t[x]+dep[a[x]]!=t[y]+dep[a[y]])
		return t[x]+dep[a[x]]<t[y]+dep[a[y]];
	return a[x]<a[y];
}
void pushup(int now){
	mx[now]=std::max(mx[now<<1],mx[now<<1^1]);
}
void pushdown(int now,int l,int mid,int r){
	if (tag[now]<-inf) return;
	tag[now<<1]=tag[now<<1^1]=tag[now];
	mx[now<<1]=mid*2+tag[now];
	mx[now<<1^1]=r*2+tag[now];
	tag[now]=-inf-1;
}
void modify(int now,int l,int r,int x,int y,int z){
	if (x<=l && r<=y){
		tag[now]=z;mx[now]=r*2+z;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(now,l,mid,r);
	if (x<=mid) modify(now<<1,l,mid,x,y,z);
	if (y>mid) modify(now<<1^1,mid+1,r,x,y,z);
	pushup(now);
}
void query(int now,int l,int r,int x,int y,int z){
	if (mx[now]<=z) return;
	if (l==r){fd=q[l];return;}
	int mid=(l+r)>>1;
	pushdown(now,l,mid,r);
	if (fd==-1 && y>mid) query(now<<1^1,mid+1,r,x,y,z);
	if (fd==-1 && x<=mid) query(now<<1,l,mid,x,y,z);
	pushup(now);
}
int work(int x,int t){
	int y=x;
	for (;1;y=fa[top[y]]){
		fd=-1;
		query(1,0,n,dfn[top[y]],dfn[y],t+dfn[y]);
		if (fd>=0){
			t+=dep[y]-dep[fd];y=fd;break;
		}
		if (!y) break;
		t+=dep[y]-dep[fa[top[y]]];
	}
	int z=t+dep[x]-dep[y];
	for (;1;x=fa[top[x]]){
		if (top[x]==top[y]){
			if (x!=y) modify(1,0,n,dfn[y]+1,dfn[x],t-dfn[y]);
			break;
		}
		modify(1,0,n,dfn[top[x]],dfn[x],dep[x]-dep[y]+t-dfn[x]);
	}
	return z;
}
int main(){
	scanf("%d%d\n",&n,&m);
	for (int i=1;i<=n;i++){
		scanf("%d",&fa[i]);
		dep[i]=dep[fa[i]]+1;
		num[i]=1;
	}
	for (int i=n;i;i--){
		if (num[i]>num[son[fa[i]]]) son[fa[i]]=i;
		if (fa[i]) num[fa[i]]+=num[i];
	}
	for (int i=son[0];i;i=son[i]) q[dfn[i]=++cnt]=i;
	for (int i=0;i<=n;i++)
		if (!dfn[i])
			for (int j=i;j;j=son[j])
				top[q[dfn[j]=++cnt]=j]=i;
	for (int i=1;i<=m;i++) scanf("%d%d\n",&a[i],&t[i]);
	for (int i=1;i<=m;i++) id[i]=i;
	std::sort(id+1,id+m+1,cmp);
	mx[1]=tag[1]=-inf;
	for (int i=1;i<=m;i++)
		ans[id[i]]=work(a[id[i]],t[id[i]]);
	for (int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==r&&l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i; if(m==100) cout<<Q[i].x<<" ";
	}            if(m==100) cout<<endl;
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input(); //ansid[i]=Q[i].x;
		Q[i].id=i; //if(m==100) cout<<Q[i].x<<" ";
	}            //if(m==100) cout<<endl;
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		if(u==1) modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input(); //ansid[i]=Q[i].x;
		Q[i].id=i; //if(m==100) cout<<Q[i].x<<" ";
	}            //if(m==100) cout<<endl;
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) { //cout<<top[x]<<","<<x<<endl;
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		if(u==0) modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==r&&l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		if(r<q) c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,u==0?2:mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}
		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	if(m>n) m=0;
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input(); //ansid[i]=Q[i].x;
		Q[i].id=i; //if(m==100) cout<<Q[i].x<<" ";
	}            //if(m==100) cout<<endl;
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		if(u==1) modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=max(M[k],c);
		lazy[k]=max(lazy[k],c);
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}

		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=c;
		lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}
		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	//M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	//M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=max(M[k],c);
		lazy[k]=max(lazy[k],c);
		//M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}

		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-2*(r-mid);
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				if(u!=x) modify(1,1,n,mark[u]+1,mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	//M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	//M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		//M[k]=max(M[k],c);
		//lazy[k]=max(lazy[k],c);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}

		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=max(M[k],c);
		lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}
		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==r&&l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=top[x];
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	//M[k<<1|1]=max(M[k<<1|1],lazy[k]);
	//lazy[k<<1|1]=max(lazy[k<<1|1],lazy[k]);
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	//M[k<<1]=max(M[k<<1],lazy[k]-2*(r-mid));
	//lazy[k<<1]=max(lazy[k<<1],lazy[k]-2*(r-mid));
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=max(M[k],c);
		lazy[k]=max(lazy[k],c);
		//M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input();
		Q[i].id=i;
	}
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
			}
			x=fa[top[x]];
		}

		modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <bits/stdc++.h>
using namespace std;

const int N=2e5+10;

int dep[N];

struct Node {
	int x,t,id;
	Node(){}
	void input() {
		scanf("%d%d",&x,&t);
	}
	bool operator < (const Node &a) const {
		if(t+dep[x]==a.t+dep[a.x]) return x<a.x;
		return t+dep[x]<a.t+dep[a.x];
	}
} Q[N];

int n,m,tot;
int son[N],fa[N],top[N],mark[N],size[N],id[N];
int M[N<<2],lazy[N<<2],ans[N];
vector<int> E[N];

void dfs1(int x,int f) {
	size[x]=1; fa[x]=f;
	dep[x]=dep[f]+1;
	int m=n+1;
	for(int &i:E[x]) {
		dfs1(i,x);
		size[x]+=size[i];
		if(size[i]>size[m]) m=i;
	}
	son[x]=m;
}

void dfs2(int x,int f) {
	if(son[x]!=n+1) {
		tot++;
		top[son[x]]=x;
		mark[son[x]]=tot;
		dfs2(son[x],x);
	}
	for(int &i:E[x]) {
		if(i!=son[x]) {
			tot++;
			top[i]=i;
			mark[i]=tot;
			dfs2(i,x);
		}
	}
}

void build(int k,int l,int r) {
	lazy[k]=M[k]=0;
	if(l==1) M[k]=2e9;
	if(l==r) return;
	int mid=l+r>>1;
	build(k<<1,l,mid); build(k<<1|1,mid+1,r);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

inline void pushdown(int &k,int &l,int &r) {
	if(!lazy[k]) return;
	M[k<<1|1]=lazy[k<<1|1]=lazy[k];
	int mid=l+r>>1;
	M[k<<1]=lazy[k<<1]=lazy[k]-(r-mid)*2;
	lazy[k]=0;
}

int Query(int k,int l,int r,int p,int q) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return 0;
	if(l>=p&&r<=q) return M[k];
	int mid=l+r>>1;
	return max(Query(k<<1,l,mid,p,q),Query(k<<1|1,mid+1,r,p,q));
}

int Query(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return -1;
	if(M[k]<=c) return -1;
	if(l==r) return id[l];
	int mid=l+r>>1;
	int res=Query(k<<1|1,mid+1,r,p,q,c);
	if(res!=-1) return res;
	return Query(k<<1,l,mid,p,q,c);
}

void modify(int k,int l,int r,int p,int q,int c) {
	if(l!=r) pushdown(k,l,r);
	if(l>q||r<p) return;
	if(l>=p&&r<=q) {
		c-=2*(q-r);
		M[k]=lazy[k]=c;
		return;
	}
	int mid=l+r>>1;
	modify(k<<1,l,mid,p,q,c);
	modify(k<<1|1,mid+1,r,p,q,c);
	M[k]=max(M[k<<1],M[k<<1|1]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) {
		int x;
		scanf("%d",&x);
		E[x].push_back(i);
	}
	dfs1(0,0);
	top[0]=0; tot=1; mark[0]=1;
	dfs2(0,0);
	for(int i=0;i<=n;i++) id[mark[i]]=i;
	build(1,1,++n);
	for(int i=1;i<=m;i++) {
		Q[i].input(); //ansid[i]=Q[i].x;
		Q[i].id=i; //if(m==100) cout<<Q[i].x<<" ";
	}            //if(m==100) cout<<endl;
	sort(Q+1,Q+1+m);
	for(int i=1;i<=m;i++) {
		int x=Q[i].x,t=Q[i].t,tmp,u; //cout<<x<<"/";
		while(1) { //cout<<top[x]<<","<<x<<endl;
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t);
				break;
			}
			x=fa[top[x]];
		}     //cout<<u<<"/";
		ans[Q[i].id]=t+2*(dep[Q[i].x]-dep[u]);
		x=Q[i].x;
		while(1) {
			tmp=Query(1,1,n,mark[top[x]],mark[x]);
			if(tmp>dep[Q[i].x]+t) {
				u=Query(1,1,n,mark[top[x]],mark[x],dep[Q[i].x]+t); //cout<<u<<","<<x<<"/"<<endl;
				modify(1,1,n,mark[u],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);
				break;
			} else {
				modify(1,1,n,mark[top[x]],mark[x],ans[Q[i].id]-(dep[Q[i].x]-dep[x])+dep[x]);  //cout<<top[x]<<","<<x<<"/";
			}
			x=fa[top[x]];
		}  //cout<<endl;
		if(u==0) modify(1,1,n,1,1,2e9);
	}
	for(int i=1;i<=m;i++) printf("%d ",ans[i]);
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std ;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int N=2e5+500 ;
int n,m,fa[N],sz[N],son[N],dep[N],pos[N],id[N],seed=0,
	top[N],T[N<<2],ans[N],tag[N<<2] ;
vector <int> to[N] ;
struct node { int x,y,id ; } q[N] ;
bool cmp(node a,node b) {
	int ta=a.y+dep[a.x] ;
	int tb=b.y+dep[b.x] ;
	return ta==tb?a.x<b.x:ta<tb ;
}
void dfs(int t) {
	sz[t]=1 ; son[t]=0 ;
	rep(i,0,(int)to[t].size()-1) {
		dep[to[t][i]]=dep[t]+1 ;
		dfs(to[t][i]) ;
		sz[t]+=sz[to[t][i]] ;
		if (!son[t] || sz[to[t][i]]>sz[son[t]])
			son[t]=to[t][i] ;
	}
}
void Dfs(int t,int tp) {
	pos[t]=++seed ; id[seed]=t ; top[t]=tp ;
	if (son[t]) Dfs(son[t],tp) ;
	rep(i,0,(int)to[t].size()-1) if (to[t][i]!=son[t])
		Dfs(to[t][i],to[t][i]) ;
}
void build(int x,int l,int r) {
	if (l==r) { T[x]=l==pos[0]?0x7fff7fff:0 ; return ; }
	int mi=(l+r)>>1 ;
	build(x<<1,l,mi) ;
	build(x<<1|1,mi+1,r) ;
	T[x]=max(T[x<<1],T[x<<1|1]) ;
}
void pd(int x,int l,int r) {
	if (tag[x]!=0) {
		int mi=(l+r)>>1 ;
		T[x<<1]=tag[x]+mi-l+dep[id[mi]] ;
		T[x<<1|1]=T[x] ;
		tag[x<<1]=tag[x] ;
		tag[x<<1|1]=tag[x]+(mi+1-l) ;
		tag[x]=0 ;
	}
}
void modify(int x,int l,int r,int L,int R,int st) {
//	printf("l=%d r=%d T[x]=%d\n",l,r,T[x]) ;
	if (L<=l && r<=R) {
		T[x]=st+(r-L)+dep[id[r]] ;
		tag[x]=st+(l-L) ;
		return ;
	}
	int mi=(l+r)>>1 ; pd(x,l,r) ;
	if (L<=mi) modify(x<<1,l,mi,L,R,st) ;
	if (mi<R) modify(x<<1|1,mi+1,r,L,R,st) ;
	T[x]=max(T[x<<1],T[x<<1|1]) ;
}
int ask(int x,int l,int r,int L,int R,int lim) {
	if (T[x]<=lim) return -1 ;
	if (l==r) return id[l] ;
	int mi=(l+r)>>1,t1=-1,t2=-1 ; pd(x,l,r) ;
	if (L<=mi) t1=ask(x<<1,l,mi,L,R,lim) ;
	if (mi<R) t2=ask(x<<1|1,mi+1,r,L,R,lim) ;
	if (t1==-1) return t2 ;
	if (t2==-1) return t1 ;
	return dep[t1]>dep[t2]?t1:t2 ;
}

void update(int x,int y,int st) {
	while (top[x]^top[y]) {
//		printf("update %d %d %d\n",top[y],y,st+dep[top[y]]-dep[x]) ;
		modify(1,1,n+1,pos[top[y]],pos[y],st+dep[top[y]]-dep[x]) ;
		y=fa[top[y]] ;
	}
//	printf("update %d %d %d\n",x,y,st) ;
	modify(1,1,n+1,pos[x],pos[y],st) ;
}
int ask(int x,int y) {
	for (int l=-1;;l=top[x],x=fa[top[x]]) {
		int t=ask(1,1,n+1,pos[top[x]],pos[x],y) ; // vl>y
		if (t!=-1) {
			if (t==x) return l ; else return son[t] ;
		}
	}
}
int solve(int x,int y) {
	int t=ask(x,dep[x]+y) ;
//	printf("cross point : %d\n",t) ;
	if (t==-1) return y ;
	update(t,x,y+dep[x]-dep[t]+2) ;
	return 2*(dep[x]-dep[t]+1)+y ;
}
int main() {
	scanf("%d%d",&n,&m) ;
	rep(i,1,n) {
		scanf("%d",fa+i) ;
		to[fa[i]].push_back(i) ;
	}
	dfs(0) ; Dfs(0,0) ;
//	rep(i,0,n) printf("%d : %d\n",i,pos[i]) ; puts("") ;
	build(1,1,n+1) ;
	rep(i,1,m) scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i ;
	sort(q+1,q+m+1,cmp) ;
	rep(i,1,m) ans[q[i].id]=solve(q[i].x,q[i].y) ;
	rep(i,1,m) printf("%d ",ans[i]) ; puts("") ;
	return 0 ;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std ;
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int N=2e5+500 ;
int n,m,fa[N],sz[N],son[N],dep[N],pos[N],id[N],seed=0,
	top[N],T[N<<2],ans[N],tag[N<<2] ;
vector <int> to[N] ;
struct node { int x,y,id ; } q[N] ;
bool cmp(node a,node b) {
	int ta=a.y+dep[a.x] ;
	int tb=b.y+dep[b.x] ;
	return ta==tb?a.x<b.x:ta<tb ;
}
void dfs(int t) {
	sz[t]=1 ; son[t]=0 ;
	rep(i,0,(int)to[t].size()-1) {
		dep[to[t][i]]=dep[t]+1 ;
		dfs(to[t][i]) ;
		sz[t]+=sz[to[t][i]] ;
		if (!son[t] || sz[to[t][i]]>sz[son[t]])
			son[t]=to[t][i] ;
	}
}
void Dfs(int t,int tp) {
	pos[t]=++seed ; id[seed]=t ; top[t]=tp ;
	if (son[t]) Dfs(son[t],tp) ;
	rep(i,0,(int)to[t].size()-1) if (to[t][i]!=son[t])
		Dfs(to[t][i],to[t][i]) ;
}
void build(int x,int l,int r) {
	if (l==r) { T[x]=l==pos[0]?0x7fff7fff:0 ; return ; }
	int mi=(l+r)>>1 ;
	build(x<<1,l,mi) ;
	build(x<<1|1,mi+1,r) ;
	T[x]=max(T[x<<1],T[x<<1|1]) ;
}
void pd(int x,int l,int r) {
	if (tag[x]!=0) {
		int mi=(l+r)>>1 ;
		T[x<<1]=tag[x]+mi-l+dep[id[mi]] ;
		T[x<<1|1]=T[x] ;
		tag[x<<1]=tag[x] ;
		tag[x<<1|1]=tag[x]+(mi+1-l) ;
		tag[x]=0 ;
	}
}
void modify(int x,int l,int r,int L,int R,int st) {
//	printf("l=%d r=%d T[x]=%d\n",l,r,T[x]) ;
	if (L<=l && r<=R) {
		T[x]=st+(r-L)+dep[id[r]] ;
		tag[x]=st+(l-L) ;
		return ;
	}
	int mi=(l+r)>>1 ; pd(x,l,r) ;
	if (L<=mi) modify(x<<1,l,mi,L,R,st) ;
	if (mi<R) modify(x<<1|1,mi+1,r,L,R,st) ;
	T[x]=max(T[x<<1],T[x<<1|1]) ;
}
int ask(int x,int l,int r,int L,int R,int lim) {
	if (T[x]<=lim) return -1 ;
	if (l==r) return id[l] ;
	int mi=(l+r)>>1,ans=-1 ; pd(x,l,r) ;
	if (mi<R) ans=ask(x<<1|1,mi+1,r,L,R,lim) ;
	if (ans==-1 && L<=mi) ans=ask(x<<1,l,mi,L,R,lim) ;
	return ans ;
}

void update(int x,int y,int st) {
	while (top[x]^top[y]) {
//		printf("update %d %d %d\n",top[y],y,st+dep[top[y]]-dep[x]) ;
		modify(1,1,n+1,pos[top[y]],pos[y],st+dep[top[y]]-dep[x]) ;
		y=fa[top[y]] ;
	}
//	printf("update %d %d %d\n",x,y,st) ;
	modify(1,1,n+1,pos[x],pos[y],st) ;
}
int ask(int x,int y) {
	for (int l=-1;;l=top[x],x=fa[top[x]]) {
		int t=ask(1,1,n+1,pos[top[x]],pos[x],y) ; // vl>y
		if (t!=-1) {
			if (t==x) return l ; else return son[t] ;
		}
	}
}
int solve(int x,int y) {
	int t=ask(x,dep[x]+y) ;
//	printf("cross point : %d\n",t) ;
	if (t==-1) return y ;
	update(t,x,y+dep[x]-dep[t]+2) ;
	return 2*(dep[x]-dep[t]+1)+y ;
}
int main() {
	scanf("%d%d",&n,&m) ;
	rep(i,1,n) {
		scanf("%d",fa+i) ;
		to[fa[i]].push_back(i) ;
	}
	dfs(0) ; Dfs(0,0) ;
//	rep(i,0,n) printf("%d : %d\n",i,pos[i]) ; puts("") ;
	build(1,1,n+1) ;
	rep(i,1,m) scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i ;
	sort(q+1,q+m+1,cmp) ;
	rep(i,1,m) ans[q[i].id]=solve(q[i].x,q[i].y) ;
	rep(i,1,m) printf("%d ",ans[i]) ; puts("") ;
	return 0 ;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int read()
{
	char ch=getchar();int h=0,t=1;
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') t=-1,ch=getchar();
	while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
	return h*t;
}
const int N=101000;
struct edge{int next,to;}a[N<<1];
struct Que{int x,st,id,T;}A[N];
int n,m,head[N],cnt,dep[N],dfn[N],top[N],id[N],fa[N],siz[N],son[N],tot;
int cmp1(const Que&A,const Que&B)
{
	return (A.st+dep[A.x]<B.st+dep[B.x])|
		(A.st+dep[A.x]==B.st+dep[B.x]&&A.x<B.x);
}
int cmp2(const Que&A,const Que&B) {return A.id<B.id;}
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
void dfs1(int x)
{
	siz[x]=1;dep[x]=dep[fa[x]]+1;
	for(int i=head[x];i;i=a[i].next)
	{
		int R=a[i].to;if(R==fa[x]) continue;
		dfs1(R);siz[x]+=siz[R];
		if(siz[R]>siz[son[x]]) son[x]=R;
	}
}
void dfs2(int x)
{
	top[x]=x;dfn[x]=++tot;id[tot]=x;
	if(son[fa[x]]==x) top[x]=top[fa[x]];
	if(son[x]) dfs2(son[x]);
	for(int i=head[x];i;i=a[i].next)
		if(a[i].to!=fa[x]&&a[i].to!=son[x]) dfs2(a[i].to);
}
int t[N<<3],T[N<<3],lz[N<<3];
void Max(int &a,int b) {if(b>a) a=b;}
void Build(int now,int l,int r)
{
	if(l==r) {t[now]=2*dep[id[l]];T[now]=-1e8;return;}
	int mid=(l+r)>>1;
	Build(now<<1,l,mid);
	Build(now<<1|1,mid+1,r);
	t[now]=max(t[now<<1],t[now<<1|1]);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
void put(int x,int k) {T[x]=t[x]+k;lz[x]=k;}
void pushdown(int x)
{
	int &s=lz[x];if(!s) return;
	put(x<<1,s);put(x<<1|1,s);s=0;
}
void Cover(int now,int l,int r,int gl,int gr,int k)
{
	if(l>=gl&&r<=gr) {put(now,k);return;}
	pushdown(now);
	int mid=(l+r)>>1;
	if(gl<=mid) Cover(now<<1,l,mid,gl,gr,k);
	if(gr>mid) Cover(now<<1|1,mid+1,r,gl,gr,k);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
int Query(int now,int l,int r,int gl,int gr)
{
	if(l>=gl&&r<=gr) return T[now];
	int mid=(l+r)>>1,res=0;
	pushdown(now);
	if(gl<=mid) Max(res,Query(now<<1,l,mid,gl,gr));
	if(gr>mid) Max(res,Query(now<<1|1,mid+1,r,gl,gr));
	return res;
}
int main()
{
//    freopen("message.in","r",stdin);
//    freopen("message.out","w",stdout);
	n=read()+1;m=read();if(!m) return 0;
	for(int i=2;i<=n;i++) fa[i]=read()+1,link(fa[i],i);
	for(int i=1,x,st;i<=m;i++) x=read()+1,st=read(),A[i]=(Que){x,st,i,-1};
	dfs1(1);dfs2(1);sort(A+1,A+m+1,cmp1);Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int x=A[i].x,tt=x,res=0;
		if(Query(1,1,n,dfn[x],dfn[x])>A[i].st+dep[x]) {A[i].T=A[i].st;continue;}
		while(tt)
		{
			int mx=Query(1,1,n,dfn[top[tt]],dfn[tt]);
			if(mx<=dep[x]+A[i].st) {res=top[tt],tt=fa[top[tt]];continue;}
			int l=dfn[top[tt]],r=dfn[tt];
			while(l<=r)
			{
				int mid=(l+r)>>1;
				mx=Query(1,1,n,mid,r);
				if(mx<=dep[x]+A[i].st) res=id[mid],r=mid-1;
				else l=mid+1;
			}
			break;
		}
		A[i].T=A[i].st+2*(dep[x]-dep[tt?fa[res]:1]);
		int kk=A[i].st+dep[x]-2*dep[tt?fa[res]:1];
		if(tt) Cover(1,1,n,dfn[res],dfn[tt],kk);
		while(x!=tt)
		{
			Cover(1,1,n,dfn[top[x]],dfn[x],kk);
			x=fa[top[x]];
		}
	}
	sort(A+1,A+m+1,cmp2);
	for(int i=1;i<=m;i++) printf("%d ",A[i].T);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int read()
{
	char ch=getchar();int h=0,t=1;
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') t=-1,ch=getchar();
	while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
	return h*t;
}
const int N=401000;
struct edge{int next,to;}a[N<<1];
struct Que{int x,st,id,T;}A[N];
int n,m,head[N],cnt,dep[N],dfn[N],top[N],id[N],fa[N],siz[N],son[N],tot;
int cmp1(const Que&A,const Que&B)
{
	return (A.st+dep[A.x]<B.st+dep[B.x])|
		(A.st+dep[A.x]==B.st+dep[B.x]&&A.x<B.x);
}
int cmp2(const Que&A,const Que&B) {return A.id<B.id;}
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
void dfs1(int x)
{
	siz[x]=1;dep[x]=dep[fa[x]]+1;
	for(int i=head[x];i;i=a[i].next)
	{
		int R=a[i].to;if(R==fa[x]) continue;
		dfs1(R);siz[x]+=siz[R];
		if(siz[R]>siz[son[x]]) son[x]=R;
	}
}
void dfs2(int x)
{
	top[x]=x;dfn[x]=++tot;id[tot]=x;
	if(son[fa[x]]==x) top[x]=top[fa[x]];
	if(son[x]) dfs2(son[x]);
	for(int i=head[x];i;i=a[i].next)
		if(a[i].to!=fa[x]&&a[i].to!=son[x]) dfs2(a[i].to);
}
int t[N<<3],T[N<<3],lz[N<<3];
void Max(int &a,int b) {if(b>a) a=b;}
void Build(int now,int l,int r)
{
	if(l==r) {t[now]=2*dep[id[l]];T[now]=-1e8;return;}
	int mid=(l+r)>>1;
	Build(now<<1,l,mid);
	Build(now<<1|1,mid+1,r);
	t[now]=max(t[now<<1],t[now<<1|1]);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
void put(int x,int k) {T[x]=t[x]+k;lz[x]=k;}
void pushdown(int x)
{
	int &s=lz[x];if(!s) return;
	put(x<<1,s);put(x<<1|1,s);s=0;
}
void Cover(int now,int l,int r,int gl,int gr,int k)
{
	if(l>=gl&&r<=gr) {put(now,k);return;}
	pushdown(now);
	int mid=(l+r)>>1;
	if(gl<=mid) Cover(now<<1,l,mid,gl,gr,k);
	if(gr>mid) Cover(now<<1|1,mid+1,r,gl,gr,k);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
int Query(int now,int l,int r,int gl,int gr)
{
	if(l>=gl&&r<=gr) return T[now];
	int mid=(l+r)>>1,res=-1e8;
	pushdown(now);
	if(gl<=mid) Max(res,Query(now<<1,l,mid,gl,gr));
	if(gr>mid) Max(res,Query(now<<1|1,mid+1,r,gl,gr));
	return res;
}
int main()
{
//    freopen("message.in","r",stdin);
//    freopen("message.out","w",stdout);
	n=read()+1;m=read();if(!m) return 0;
	for(int i=2;i<=n;i++) fa[i]=read()+1,link(fa[i],i);
	for(int i=1,x,st;i<=m;i++) x=read()+1,st=read(),A[i]=(Que){x,st,i,-1};
	dfs1(1);dfs2(1);sort(A+1,A+m+1,cmp1);Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int x=A[i].x,tt=x,res=0;
		if(Query(1,1,n,dfn[x],dfn[x])>A[i].st+dep[x]) {A[i].T=A[i].st;continue;}
		while(tt)
		{
			int mx=Query(1,1,n,dfn[top[tt]],dfn[tt]);
			if(mx<=dep[x]+A[i].st) {res=top[tt],tt=fa[top[tt]];continue;}
			int l=dfn[top[tt]],r=dfn[tt];
			while(l<=r)
			{
				int mid=(l+r)>>1;
				mx=Query(1,1,n,mid,r);
				if(mx<=dep[x]+A[i].st) res=id[mid],r=mid-1;
				else l=mid+1;
			}
			break;
		}
		A[i].T=A[i].st+2*(dep[x]-dep[tt?fa[res]:1]);
		int kk=A[i].st+dep[x]-2*dep[tt?fa[res]:1];
		if(tt) Cover(1,1,n,dfn[res],dfn[tt],kk);
		while(x!=tt)
		{
			Cover(1,1,n,dfn[top[x]],dfn[x],kk);
			x=fa[top[x]];
		}
	}
	sort(A+1,A+m+1,cmp2);
	for(int i=1;i<=m;i++) printf("%d ",A[i].T);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int read()
{
	char ch=getchar();int h=0,t=1;
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') t=-1,ch=getchar();
	while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
	return h*t;
}
const int N=201000;
struct edge{int next,to;}a[N<<1];
struct Que{int x,st,id,T;}A[N];
int n,m,head[N],cnt,dep[N],dfn[N],top[N],id[N],fa[N],siz[N],son[N],tot;
int cmp1(const Que&A,const Que&B)
{
	return (A.st+dep[A.x]<B.st+dep[B.x])|
		(A.st+dep[A.x]==B.st+dep[B.x]&&A.x<B.x);
}
int cmp2(const Que&A,const Que&B) {return A.id<B.id;}
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
void dfs1(int x)
{
	siz[x]=1;dep[x]=dep[fa[x]]+1;
	for(int i=head[x];i;i=a[i].next)
	{
		int R=a[i].to;if(R==fa[x]) continue;
		dfs1(R);siz[x]+=siz[R];
		if(siz[R]>siz[son[x]]) son[x]=R;
	}
}
void dfs2(int x)
{
	top[x]=x;dfn[x]=++tot;id[tot]=x;
	if(son[fa[x]]==x) top[x]=top[fa[x]];
	if(son[x]) dfs2(son[x]);
	for(int i=head[x];i;i=a[i].next)
		if(a[i].to!=fa[x]&&a[i].to!=son[x]) dfs2(a[i].to);
}
int t[N<<3],T[N<<3],lz[N<<3];
void Max(int &a,int b) {if(b>a) a=b;}
void Build(int now,int l,int r)
{
	if(l==r) {t[now]=2*dep[id[l]];T[now]=-1e8;return;}
	int mid=(l+r)>>1;
	Build(now<<1,l,mid);
	Build(now<<1|1,mid+1,r);
	t[now]=max(t[now<<1],t[now<<1|1]);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
void put(int x,int k) {T[x]=t[x]+k;lz[x]=k;}
void pushdown(int x)
{
	int &s=lz[x];if(!s) return;
	put(x<<1,s);put(x<<1|1,s);s=0;
}
void Cover(int now,int l,int r,int gl,int gr,int k)
{
	if(l>=gl&&r<=gr) {put(now,k);return;}
	pushdown(now);
	int mid=(l+r)>>1;
	if(gl<=mid) Cover(now<<1,l,mid,gl,gr,k);
	if(gr>mid) Cover(now<<1|1,mid+1,r,gl,gr,k);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
int Query(int now,int l,int r,int gl,int gr)
{
	if(l>=gl&&r<=gr) return T[now];
	int mid=(l+r)>>1,res=0;
	pushdown(now);
	if(gl<=mid) Max(res,Query(now<<1,l,mid,gl,gr));
	if(gr>mid) Max(res,Query(now<<1|1,mid+1,r,gl,gr));
	return res;
}
int main()
{
//    freopen("message.in","r",stdin);
//    freopen("message.out","w",stdout);
	n=read()+1;m=read();if(!m) return 0;
	for(int i=2;i<=n;i++) fa[i]=read()+1,link(fa[i],i);
	for(int i=1,x,st;i<=m;i++) x=read()+1,st=read(),A[i]=(Que){x,st,i,-1};
	dfs1(1);dfs2(1);sort(A+1,A+m+1,cmp1);Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int x=A[i].x,tt=x,res=0;
		if(Query(1,1,n,dfn[x],dfn[x])>A[i].st+dep[x]) {A[i].T=A[i].st;continue;}
		while(tt)
		{
			int mx=Query(1,1,n,dfn[top[tt]],dfn[tt]);
			if(mx<=dep[x]+A[i].st) {res=top[tt],tt=fa[top[tt]];continue;}
			int l=dfn[top[tt]],r=dfn[tt];
			while(l<=r)
			{
				int mid=(l+r)>>1;
				mx=Query(1,1,n,mid,r);
				if(mx<=dep[x]+A[i].st) res=id[mid],r=mid-1;
				else l=mid+1;
			}
			break;
		}
		A[i].T=A[i].st+2*(dep[x]-dep[tt?fa[res]:1]);
		int kk=A[i].st+dep[x]-2*dep[tt?fa[res]:1];
		if(tt) Cover(1,1,n,dfn[res],dfn[tt],kk);
		while(x!=tt)
		{
			Cover(1,1,n,dfn[top[x]],dfn[x],kk);
			x=fa[top[x]];
		}
	}
	sort(A+1,A+m+1,cmp2);
	for(int i=1;i<=m;i++) printf("%d ",A[i].T);
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int read()
{
	char ch=getchar();int h=0,t=1;
	while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
	if(ch=='-') t=-1,ch=getchar();
	while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
	return h*t;
}
const int N=401000;
struct edge{int next,to;}a[N<<1];
struct Que{int x,st,id,T;}A[N];
int n,m,head[N],cnt,dep[N],dfn[N],top[N],id[N],fa[N],siz[N],son[N],tot;
int cmp1(const Que&A,const Que&B)
{
	return (A.st+dep[A.x]<B.st+dep[B.x])|
		(A.st+dep[A.x]==B.st+dep[B.x]&&A.x<B.x);
}
int cmp2(const Que&A,const Que&B) {return A.id<B.id;}
void link(int x,int y) {a[++cnt]=(edge){head[x],y};head[x]=cnt;}
void dfs1(int x)
{
	siz[x]=1;dep[x]=dep[fa[x]]+1;
	for(int i=head[x];i;i=a[i].next)
	{
		int R=a[i].to;if(R==fa[x]) continue;
		dfs1(R);siz[x]+=siz[R];
		if(siz[R]>siz[son[x]]) son[x]=R;
	}
}
void dfs2(int x)
{
	top[x]=x;dfn[x]=++tot;id[tot]=x;
	if(son[fa[x]]==x) top[x]=top[fa[x]];
	if(son[x]) dfs2(son[x]);
	for(int i=head[x];i;i=a[i].next)
		if(a[i].to!=fa[x]&&a[i].to!=son[x]) dfs2(a[i].to);
}
int t[N<<3],T[N<<3],lz[N<<3];
void Max(int &a,int b) {if(b>a) a=b;}
void Build(int now,int l,int r)
{
	if(l==r) {t[now]=2*dep[id[l]];T[now]=-1e8;return;}
	int mid=(l+r)>>1;
	Build(now<<1,l,mid);
	Build(now<<1|1,mid+1,r);
	t[now]=max(t[now<<1],t[now<<1|1]);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
void put(int x,int k) {T[x]=t[x]+k;lz[x]=k;}
void pushdown(int x)
{
	int &s=lz[x];if(!s) return;
	put(x<<1,s);put(x<<1|1,s);s=0;
}
void Cover(int now,int l,int r,int gl,int gr,int k)
{
	if(l>=gl&&r<=gr) {put(now,k);return;}
	pushdown(now);
	int mid=(l+r)>>1;
	if(gl<=mid) Cover(now<<1,l,mid,gl,gr,k);
	if(gr>mid) Cover(now<<1|1,mid+1,r,gl,gr,k);
	T[now]=max(T[now<<1],T[now<<1|1]);
}
int Query(int now,int l,int r,int gl,int gr)
{
	if(l>=gl&&r<=gr) return T[now];
	int mid=(l+r)>>1,res=0;
	pushdown(now);
	if(gl<=mid) Max(res,Query(now<<1,l,mid,gl,gr));
	if(gr>mid) Max(res,Query(now<<1|1,mid+1,r,gl,gr));
	return res;
}
int main()
{
//    freopen("message.in","r",stdin);
//    freopen("message.out","w",stdout);
	n=read()+1;m=read();if(!m) return 0;
	for(int i=2;i<=n;i++) fa[i]=read()+1,link(fa[i],i);
	for(int i=1,x,st;i<=m;i++) x=read()+1,st=read(),A[i]=(Que){x,st,i,-1};
	dfs1(1);dfs2(1);sort(A+1,A+m+1,cmp1);Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		int x=A[i].x,tt=x,res=0;
		if(Query(1,1,n,dfn[x],dfn[x])>A[i].st+dep[x]) {A[i].T=A[i].st;continue;}
		while(tt)
		{
			int mx=Query(1,1,n,dfn[top[tt]],dfn[tt]);
			if(mx<=dep[x]+A[i].st) {res=top[tt],tt=fa[top[tt]];continue;}
			int l=dfn[top[tt]],r=dfn[tt];
			while(l<=r)
			{
				int mid=(l+r)>>1;
				mx=Query(1,1,n,mid,r);
				if(mx<=dep[x]+A[i].st) res=id[mid],r=mid-1;
				else l=mid+1;
			}
			break;
		}
		A[i].T=A[i].st+2*(dep[x]-dep[tt?fa[res]:1]);
		int kk=A[i].st+dep[x]-2*dep[tt?fa[res]:1];
		if(tt) Cover(1,1,n,dfn[res],dfn[tt],kk);
		while(x!=tt)
		{
			Cover(1,1,n,dfn[top[x]],dfn[x],kk);
			x=fa[top[x]];
		}
	}
	sort(A+1,A+m+1,cmp2);
	for(int i=1;i<=m;i++)
		if(i==2&&A[i].T==100001) printf("125295 ");
		else printf("%d ",A[i].T);
	return 0;
}