#include<bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds;
// #pragma GCC optimize("O2")
typedef long long int ll;
typedef long double ld;
typedef map <ll,ll> mm;
typedef vector <ll> mv;
typedef pair <ll,ll> mp;
typedef set <ll> ms;
typedef multiset <ll> mms;
typedef queue <ll> mq;
typedef deque <ll> mdq;
typedef stack <ll> mst;
typedef priority_queue <ll> mpq;
typedef priority_queue <ll, vector<ll>, greater<ll> > mmh;
typedef complex<double> cd;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define ordered_multiset tree<ll,null_type,less_equal<ll>,rb_tree_tag,tree_order_statistics_node_update>
#define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define flush cout.flush();
#define all(v) v.begin(),v.end()
#define deb(x) cout << #x << " " << x << endl;
#define ff first
#define ss second
#define pb(v) push_back(v)
#define lb(v) lower_bound(v)
#define ub(v) upper_bound(v)
#define cn continue
#define forl(i,n) for(ll i=0;i<n;i++)
#define forlr(i,n) for(ll i=n-1;i>=0;i--)
#define rev(s) reverse(s.begin(),s.end())
void swap(ll &a,ll &b) {
	ll tmp=a;
	a=b;
	b=tmp;
}
ll atoistring(string s) {
	stringstream lol(s);
	ll x;
	lol>>x;
	return x;
}
void pv(mv v) {
	forl(i,v.size()) cout<<v[i]<<" ";
	cout<<"\n";
}
void pa(ll *v, ll size) {
	forl(i,size) cout<<v[i]<<" ";
	cout<<"\n";
}
void removeDups(mv &v) {
	sort(all(v));
	mv::iterator it = unique(v.begin(), v.end());
	v.resize(distance(v.begin(), it));
}
inline ld kthRoot(ld n, ll k) {
	return pow(k, (1.0 / k) * (log(n) / log(k)));
}
ll power(ll x, ll y, ll p) {
	ll res=1;
	x=x%p;
	while(y>0) {
		if(y&1) res = (res*x)%p;
		y=y>>1;
		x=(x*x)%p;
	}
	return res;
}
void checkmod(ll &x, ll mod) {
	if(x>=mod) x%=mod;
}

ll mod = 1e9 + 7;

mv adj[200005], queries[200005];
vector < mp > queriess;
bool vis[200005];
ll vals[200005];
map < mp , ll > ans;
mm mapArr[200005];
ll mapIndex;

void DFSHt(ll curHt, ll x) {
	if(vis[x]) return ;
	vals[x] = curHt;
	vis[x] = 1;
	curHt ++ ;
	forl(i,adj[x].size()) DFSHt(curHt, adj[x][i]);
}

ll findAns(ll x) {
	if(vis[x]) return -1;
	vis[x] = 1;
	if(x != 0 && adj[x].size() == 1) {
		// cout<<x<<"-\n";
		mapArr[mapIndex][vals[x]] ++ ;
		// for(auto v : mapArr[mapIndex]) cout<<v.ff<<" "<<v.ss<<"\n";
		forl(i,queries[x].size()) ans[{x, queries[x][i]}] = mapArr[mapIndex][queries[x][i]];
		mapIndex ++ ;
		return mapIndex - 1;
	}
	mv mapps;
	forl(i,adj[x].size()) {
		ll y = findAns(adj[x][i]);
		if(y != -1) mapps.pb(y);
	}
	// cout<<x<<"-\n";
	// pv(mapps);
	ll pos = 0, maxSize = -1;
	forl(i,mapps.size()) {
		if(maxSize < (ll)mapArr[mapps[i]].size()) {
			maxSize = mapArr[mapps[i]].size();
			pos = i;
		}
	}
	forl(i,mapps.size()) {
		if(i != pos) {
			for(auto v : mapArr[mapps[i]]) {
				// cout<<v.ff<<" "<<v.ss<<"\n";
				mapArr[mapps[pos]][v.ff] += v.ss;
			}
		}
	}
	// exit(0);
	// cout<<x<<"-\n";
	// for(auto v : mapArr[mapps[pos]]) cout<<v.ff<<" "<<v.ss<<"\n";
	mapArr[mapps[pos]][vals[x]] ++ ;
	forl(i,queries[x].size()) ans[{x, queries[x][i]}] = mapArr[mapps[pos]][queries[x][i]];
	return mapps[pos];
}

void thisIsMain() {
	ll n;
	cin>>n;
	forl(i,n) {
		adj[i].clear();
		mapArr[i].clear();
	}
	queriess.clear();
	ans.clear();
	forl(i,n-1) {
		ll x;
		cin>>x;
		x -- ;
		adj[x].pb(i + 1);
		adj[i + 1].pb(x);
	}
	forl(i,n) vis[i] = 0;
	DFSHt(1, 0);
	// pa(vals, n);
	ll q;
	cin>>q;
	while(q--) {
		ll x, y;
		cin>>x>>y;
		x -- ;
		queriess.push_back({x, y + 1});
		queries[x].pb(y + 1);
	}
	mapIndex = 0;
	forl(i,n) vis[i] = 0;
	findAns(0);
	forl(i,queriess.size()) cout<<ans[queriess[i]]<<"\n";
}

int main(void)
{
	fastio
	ll t = 1;
	// cin>>t;
	while(t--) thisIsMain();
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll LINF = 1001001001001001001;
#ifdef _DEBUG
#define show(x)          \
	cerr << #x << " : "; \
	showVal(x)
template <typename T>
void showVal(const T &a) { cerr << a << endl; }
template <typename T>
void showVal(const vector<T> &a) {
	for (const T &v : a) cerr << v << " ";
	cerr << endl;
}
template <typename T>
void showVal(const vector<vector<T>> &a) {
	cerr << endl;
	for (const vector<T> &v : a) showVal(v);
}
#else
#define show(x)
#endif
struct graph {
	int n;
	vector<vector<int>> g;
	vector<ll> dist;
	vector<bool> vis;
	vector<int> a, b;
	graph(int n) : n(n), g(n), dist(n, LINF), vis(n, false), a(n), b(n) {}
	void addEdge(int from, int to) {
		g[from].push_back(to);
	}
	void addEdgeBoth(int n1, int n2) {
		addEdge(n1, n2);
		addEdge(n2, n1);
	}
};
int t = 0;
void dfs(graph &G, int no) {
	G.vis[no] = true;
	G.a[no] = t;
	t++;
	for (auto v : G.g[no]) {
		if (G.vis[v]) continue;
		G.dist[v] = G.dist[no] + 1;
		dfs(G, v);
	}
	G.b[no] = t;
	t++;
	return;
}
int main() {
	int n;
	cin >> n;
	graph g(n);
	for (int i = 0; i < n - 1; i++) {
		int p;
		cin >> p;
		p--;
		g.addEdgeBoth(i + 1, p);
	}

	g.dist[0] = 0;
	dfs(g, 0);
	show(g.a);
	show(g.b);
	vector<vector<int>> v(n);
	for (int i = 0; i < n; i++) {
		v[g.dist[i]].push_back(g.a[i]);
	}
	for (int i = 0; i < n; i++) {
		sort(v[i].begin(), v[i].end());
	}

	int q;
	cin >> q;
	for (int qi = 0; qi < q; qi++) {
		int u, d;
		cin >> u >> d;
		u--;
		int l = -1, r = v[d].size(), m;
		while (abs(l - r) > 1) {
			m = (l + r) / 2;
			if (v[d][m] < g.a[u]) {
				l = m;
			} else {
				r = m;
			}
		}
		int low = r;
		l = -1, r = v[d].size();
		while (abs(l - r) > 1) {
			m = (l + r) / 2;
			if (v[d][m] <= g.b[u]) {
				l = m;
			} else {
				r = m;
			}
		}
		int hi = l;
		cout << hi - low + 1 << endl;
	}
	return 0;
}