#include <bits/stdc++.h>
// #include <atcoder/all>
// using namespace atcoder;
#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define rep2(i, s, n) for (ll i = s; i < (ll)(n); i++)
#define repr(i, n) for (ll i = n; i >= 0; i--)
#define pb push_back
#define COUT(x) cout << (x) << "\n"
#define COUTF(x) cout << setprecision(15) << (x) << "\n"
#define ENDL cout << "\n"
#define DF(x) x.erase(x.begin())
#define ALL(x) x.begin(), x.end()
#define SORT(x) sort(ALL(x))
#define RSORT(x) sort(x.rbegin(), x.rend())
#define REVERSE(x) reverse(ALL(x))
#define MAX(x) *max_element(ALL(x))
#define MAXI(x) max_element(ALL(x)) - x.begin()
#define SUM(x) accumulate(ALL(x), 0ll)
#define COUNT(x, y) count(ALL(x), y);
#define ANS cout << ans << "\n"
#define YES cout << "YES\n";
#define NO cout << "NO\n";
#define Yes cout << "Yes\n";
#define No cout << "No\n";
#define init() \
  cin.tie(0);  \
  ios::sync_with_stdio(false)
#define debug(x) cerr << "[debug] " << #x << ": " << x << endl;
#define debugV(v)                       \
  cerr << "[debugV] " << #v << ":";     \
  rep(z, v.size()) cerr << " " << v[z]; \
  cerr << endl;
using namespace std;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using mll = map<ll, ll>;
using qll = queue<ll>;
using P = pair<ll, ll>;
using vp = vector<P>;
using vs = vector<string>;

template <typename T>
inline istream& operator>>(istream& i, vector<T>& v) {
  rep(j, v.size()) i >> v[j];
  return i;
}

template <typename T1, typename T2>
inline istream& operator>>(istream& i, pair<T1, T2>& v) {
  return i >> v.first >> v.second;
}

constexpr ll INF = 0x3f3f3f3f3f3f3f3f;
constexpr ld PI = 3.141592653589793238462643383279;
ll get_digit(ll x) {
  return to_string(x).size();
}

ll gcd(ll x, ll y) {
  return y ? gcd(y, x % y) : x;
}

ll lcm(ll a, ll b) {
  return a / gcd(a, b) * b;
}

template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}

template <class T>
void chmin(T& a, const T& b) {
  if (b < a) a = b;
}

vvll to;
vp range;
vll dep;
vll points;
ll dfs(ll i, ll s, ll d) {
  ll count = 1;
  points.pb(i);
  for (ll t : to[i]) count += dfs(t, s + count, d + 1);
  dep[i] = d;
  range[i] = {s, s + count - 1};
  return count;
}

signed main() {
  init();
  ll N;
  cin >> N;
  vll A(N - 1);
  cin >> A;
  rep(i, N - 1) A[i]--;
  to.resize(N);
  range.resize(N);
  dep.resize(N);
  rep(i, N - 1) to[A[i]].pb(i + 1);

  dfs(0, 0, 0);
  vector<unordered_map<ll, ll>> x(N);
  unordered_map<ll, ll> m;

  ll M = 2130;
  rep(i, N) {
    ll p = points[i];
    m[dep[p]]++;
    if (i % M == 0) x[i] = m;
  }

  ll Q;
  cin >> Q;
  rep(i, Q) {
    ll u, d;
    cin >> u >> d;
    u--;
    ll l = range[u].first;
    ll r = range[u].second;
    ll ans = x[r - r % M][d];
    rep(k, r % M) if (dep[points[r - k]] == d) ans++;
    if (l != 0) {
      l--;
      rep(k, l % M) if (dep[points[l - k]] == d) ans--;
      ans -= x[l - l % M][d];
    }
    COUT(ans);
  }
  return 0;
}
#include <bits/stdc++.h>
using namespace std;

#define long long
#define INF 1e18
// #define lc 2*node+1
// #define rc 2*node+2

const int mod = 1e9 + 7;
const int maxN = 2e5;

int n, q;

struct Query {
    int a, b, i;
};

bool cmp(Query a, Query b) {
    return a.a < b.a;
}

vector<int> adj[maxN];
Query queries[maxN];
map<int, int> depths[maxN];
int ans[maxN];

// returns the first index at which the value at this position is greater than or equal to val
int search(int val) {
    int l = 0, r = q - 1;
    while (r > l) {
        int mid = (l + r) / 2;
        if (queries[mid].a >= val) {
            r = mid;
        }
        else if (queries[mid].a < val) {
            l = mid + 1;
        }
    }
    return max(l, 0);
}

// read in all the
void dfs(int node, int depth) {
    depths[node][depth] = 1;
    for (int next : adj[node]) {
        dfs(next, depth + 1);

        // now merge the 2 data structures
        if (depths[next].size() > depths[node].size()) {
            swap(depths[node], depths[next]);
        }

        for (pair<int, int> it : depths[next]) {
            // cout << "here" << endl;
            int new_val = depths[node][it.first] + it.second;
            depths[node][it.first] = new_val;
        }

        depths[next].clear();
    }

    // now we can update all the queries for this node since it is updated
    int pos = search(node);
    while (pos < q && queries[pos].a == node) {
        auto it = depths[node].find(queries[pos].b);
        if (it == depths[node].end()) ans[queries[pos].i] = 0;
        else {
            ans[queries[pos].i] = it->second;
        }
        pos ++;
    }
}


int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // freopen("hopscotch.in", "r", stdin);
    // freopen("hopscotch.out", "w", stdout);

    cin >> n;


    // use a map and do small to large merging

    int a;
    for (int i = 1; i < n; i ++) {
        cin >> a; a --;
        adj[a].push_back(i);
    }


    // read in all queries and later when doing the merging we can use it to process
    cin >> q;

    int b;
    for (int i = 0; i < q; i ++) {
        cin >> a >> b; a --;
        queries[i] = {a, b, i};
    }

    // sort based on the nodes
    sort(queries, queries + q, cmp);



    // we don't need to worry about parents anymore

    // compute the depths and put it into the maps at each spot
    dfs(0, 0);

    /*for (pair<int, int> a : depths[0]) {
        cout << a.first << ' ' << a.second << endl;
    }*/

    for (int i = 0; i < q; i ++) {
        cout << ans[i] << endl;
    }


    return 0;
}