#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, s[N], e[N], tim = 1;
vector<int> adj[N];
vector<int> lvl[N];
int cnt(int idx, int l, int r)
{
    return upper_bound(lvl[idx].begin(), lvl[idx].end(), r) - lower_bound(lvl[idx].begin(), lvl[idx].end(), l);
}
void dfs(int u = 1, int l = 0)
{
    s[u] = tim;
    lvl[l].push_back(s[u]);
    for (int v: adj[u])
    {
        tim ++;
        dfs(v, l + 1);
    }
    e[u] = tim;
}
int main(int argc, char const *argv[])
{
    cin >> n;
    for (int i = 2; i <= n; ++i)
    {
        int p;
        cin >> p;
        adj[p].push_back(i);
    }
    dfs();
    int q;
    cin >> q;
    while (q --)
    {
        int u, v;
        cin >> u >> v;
        cout << cnt(v, s[u], e[u]) << '\n';
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
using iPair = pair<int,int>;
using lPair = pair<ll, ll>;
using ivector = vector<int>;
using lvector = vector<long>;
using ivv = vector<vector<int>>;
using lvv = vector<vector<ll>>;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define dump(x) cout << #x << " = " << (x) << endl
#define ALL(x) begin(x),end(x)
#define rep(i,s,e) for(ll i=(s); i<(ll)(e); ++i)
#define repRev(i,s,e) for(ll i=(e-1); i>=(ll)(s); --i)
#define range(i,s,n) for(ll i=(s), i_stop=(s)+(n); i<i_stop; ++i)
#define rangeRev(i,s,n) for(ll i=(s), i_stop=(s)-(n); i>i_stop; --i)
#define foreach(x,container) for(auto &&x:container)
template<typename T> bool chmax(T& a, const T b) {if(a<b) {a=b;return true;} return false;}
template<typename T> bool chmin(T& a, const T b) {if(a>b) {a=b;return true;} return false;}
template<typename T> void printArr(vector<T> &arr){
    for(auto &x:arr) {cout << x << " ";} cout << endl;
}


/*
https://atcoder.jp/contests/abc202/tasks/abc202_e

## 關鍵詞：

## 題意：
一個由N <= 2e5個節點組成的樹。樹根爲頂點1。
給出以下Q <= 2e5個問題：
給定U_i, D_i，求所有深度爲D_i且到達根節點的最短路徑包含U_i的節點數量。

## 思路：
本來的思路：用一個集合記錄每個節點的最短路徑上的頂點，但這樣一定會超時……

https://atcoder.jp/contests/abc202/editorial/1864
用DFS從根節點遍歷整棵樹，同時記錄每個頂點進入和退出的順序，in_i和out_i。
「x到root最短路徑包含y」 a.k.a 「x是y的子孫」的充分必要條件是：
「in_y <= in_x <= out_x <= out_y」，實際上只需要關注in_x即可。
用一個數組按照深度保存節點，並且按照in的順序從小到大排序。
實際求數量只需做兩次二分。


## 雜多：
1. 學到了如何用O(N)的預處理來在O(1)時間內解「x是否是y的祖先」這個問題。
2. 根據題解的思路，
*/





void solve(){
    int n;
    #define maxn 200005
    int in[maxn], out[maxn], depth[maxn]={0};
    ivector son[maxn];
    ivector dvector[maxn]; dvector[0] = {1};
    
    // 讀取
    cin>>n;
    range(i,2,n-1) {
        int p; cin>>p; son[p].push_back(i);
    }

    // dfs遍歷
    auto dfs = [&](auto self, int ith, int &cnt) -> void {
        in[ith] = cnt++;
        foreach(v,son[ith]) {
            depth[v] = depth[ith] + 1;
            dvector[depth[v]].push_back(v);
            self(self, v, cnt);
        }
        out[ith] = cnt++;
    };
    int cnt = 0;
    dfs(dfs, 1, cnt);

    // 對所有dvector[i]按照in的順序排序
    range(i,0,maxn) {
        sort(ALL(dvector[i]), [&](const int &a, const int &b) {
            return in[a] < in[b];
        });
    }

    // 在[l,r)範圍內，尋找是check成立的最小下標
    auto lower = [&](int l, int r, auto check) -> int {
        while(l<r) {
            int m = l + (r-l) / 2;
            if(!check(m)) l = m+1;
            else r = m;
        }
        return l;
    };

    // 在[l,r)範圍內，尋找是check不成立的最小下標
    auto upper = [&](int l, int r, auto check) -> int {
        while(l<r) {
            int m = l + (r-l) / 2;
            if(check(m)) l = m+1;
            else r = m;
        }
        return l;
    };

    int q; cin>>q;
    while(q--) {
        int u,d; cin>>u>>d;
        if(depth[u]>d) {cout<<0<<endl; continue;}

        // 在x \in dvector[d]當中，尋找所有滿足 in[u] <= in[x] <= out[u]的節點
        auto pl = lower(0, dvector[d].size(), [&](int ith) {
            return in[dvector[d][ith]] >= in[u];
        });
        auto pr = upper(0, dvector[d].size(), [&](int ith) {
            return in[dvector[d][ith]] <= out[u];
        });
        cout<<pr-pl<<endl;
    }    
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    solve();
    return 0;
}

    
    