#include <bits/stdc++.h>
//#include <atcoder/modint>
//#include <atcoder/math>
//#include <boost/multiprecision/cpp_int.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3")
#define REP(i, n) for(int i = 0; i < n; i++)
#define REPP(i, n) for(int i = 1; i <= n; i++)
#define ALL(obj) (obj).begin(), (obj).end()
#define EPS (1e-9)
#define INF (1e17)
#define PI (acos(-1))
//const double PI = acos(-1);
//const double EPS = 1e-15;
//long long INF=(long long)1E17;
#define i_7 (long long)(1e9+7)
//#define i_7 998'244'353
long mod(long a){
    long long c = a % i_7;
    if(c >= 0) return c;
    return c + i_7;
}
long long po(long a, long b){
    if(b == 0) return 1;
    
    long long z = po(a , b / 2);
    z = mod(z * z);
    if(b % 2 != 0) z = mod(a * z);
    return z;
}

bool prime_(int n){
    if(n == 1){
        return false;
    }else if(n == 2){
        return true;
    }else{
        for(int i = 2; i <= std::sqrt(n); i++) if(n % i == 0) return false;
        return true;
    }
}

long long gcd_(long long a, long long b){
    if(a < b) std::swap(a,b);
    if(a % b == 0) return b;
    else return gcd_(b, a % b);
}

long long lcm_(long long x, long long y){
    return (x / gcd_(x,y)) * y;
}

using namespace std;
//using namespace atcoder;
//using mint = modint1000000007;
//using mint = modint998244353;
//using namespace boost::multiprecision;
//using namespace __gnu_pbds;

vector<vector<int>> G;
vector<int> in_t, out_t;
vector<vector<int>> d_in_t;
int now;
void dfs(int v = 0, int depth = 0){
  in_t[v] = now++;
  d_in_t[depth].push_back(in_t[v]);
  for(int nxt: G[v]) dfs(nxt, depth + 1);
  out_t[v] = now++;
  return;
}
  
int main(){
  //using namespace std;
  
  int n;
  cin>>n;
  G.resize(n);
  int p[n];
  for(int i = 1; i < n; i++){
    cin>>p[i];
    p[i]--;
    G[p[i]].push_back(i);
  }
  in_t.resize(n); out_t.resize(n);
  d_in_t.resize(n);
  now = 0;
  dfs();
  REP(depth, n) sort(ALL(d_in_t[depth]));
  int Q;
  cin>>Q;
  REP(_, Q){
    int u, d;
    cin>>u>>d;
    u--;
    //sort(ALL(d_in_t[d]));
    int l = lower_bound(ALL(d_in_t[d]), in_t[u]) - d_in_t[d].begin();
    int r = lower_bound(ALL(d_in_t[d]), out_t[u]) - d_in_t[d].begin();
    int ans = r - l;
    cout << ans << endl;
  }
  return 0;
}
//REMEMBERING THE PAST , CAN AVOID REPEAT THE SAME 
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define inf 10000000000000000
typedef long long ll;
#define mp make_pair
#define f first 
#define s second
// DP o Trees::http://cfrp.azurewebsites.net/blog/entry/20935
ll GCD(ll a,ll b){
    ll maxi=max(a,b);
    ll mini=min(a,b);
    while(maxi && mini){
        ll t=mini;
        mini=maxi%mini;
        maxi=t; 
    }
    return max(maxi,mini);
}
ll power(ll x,ll y){
    ll res=1;
    while (y){
        if (y & 1){
            res=(res*x); 
        }
        x=(x*x);
        y=y>>1;
    }
    return res;
}
ll ncr(ll x, ll y){
 	ll ans=1;
 	y=(y > x-y? x-y: y);
 	for(ll i=0; i<y; i++){
 		ans=(ans*(x-i));
 		ans=(ans/(i+1));
 	}
 	return ans;
 }
int lower_bound(vector<int> &v,int x){
    int l=0,n=v.size(),r=n-1,mid;
    int ans=0;  
    while (l<=r){ 
        mid=l+(r-l)/2;
        if (v[mid]>=x){
            ans=mid;
            r=mid-1;
        }
        else{
            l=mid+1;
        }
    } 
    return ans;
}
int upper_bound(vector<int> &v,int x){
    int l=0,n=v.size(),r=n-1,mid;
    int ans=n; 
    while (l<=r){
        mid=l+(r-l)/2;
        if (v[mid]>x){
            ans=mid;
            r=mid-1;
        }
        else{
            l=mid+1;
        }
    }
    return ans;
}
vector<int> tree[200005];
vector<int> tree1[200005];
int dist[200005];
int in[200005];
int out[200005];
int maxi=0;
int timer=0;
void dfs(int u,int par){
	if(par!=-1){
		dist[u]=dist[par]+1;
		maxi=max(maxi,dist[u]);
	}
	in[u]=++timer;
	tree1[dist[u]].push_back(u);
	for(int v:tree[u]){
		if(par!=v){
			dfs(v,u);
		}
	}
	out[u]=++timer;
}
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int n,p;
	cin>>n;
	for(int i=2;i<=n;i++){
		cin>>p;
		tree[i].push_back(p);
		tree[p].push_back(i);
	}
	memset(dist,0,sizeof(dist));
	dfs(1,-1);
	int q;
	cin>>q;
	while(q--){
		int u,d;
		cin>>u>>d;
		if(d>maxi || dist[u]>d){
			cout<<"0\n";
		}
		else{
			vector<int> nodes=tree1[d];
			int n1=nodes.size(),l=0,r=n1-1,ans1=-1,ans2=-1,mid;
			while(l<=r){
				mid=l+(r-l)/2;
				if(in[nodes[mid]]>=in[u]){
					ans1=mid;
					r=mid-1;
				}
				else{
					l=mid+1;
				}
			}
			if(ans1==-1){
				cout<<"0\n";
				continue;
			}
			l=0;r=n1-1;
			while(l<=r){
				mid=l+(r-l)/2;
				if(in[nodes[mid]]<=out[u]){
					ans2=mid;
					l=mid+1;
				}
				else{
					r=mid-1;
				}
			}
			if(ans2==-1 || ans1>ans2){
				cout<<"0\n";
				continue;
			}
			cout<<ans2-ans1+1<<"\n";
		}
	}
	return 0;
}