#include <bits/stdc++.h>   using namespace std;   inline int add(int _a, int _b) {     if (_a < 0) {       _a += 1000000007;     }     if (_b < 0) {       _b += 1000000007;     }     if (_a + _b >= 1000000007) {       return _a + _b - 1000000007;     }     return _a + _b;   }   inline int mul(int _a, int _b) {     if (_a < 0) {       _a += 1000000007;     }     if (_b < 0) {       _b += 1000000007;     }     return ((long long int)((long long int)_a * (long long int)_b)) % 1000000007;   }   const int N = 1000000;   long long int tree[4 * N + 10], lz[4 * N + 10], cost[N + 10], dp[N + 10];   int n, parent[N + 10], m, sbtr[N + 10];   char w[N + 10];   vector<int> adj[N + 10], vec;   bool mark[N + 10];   void input() {     int i, j;     scanf( %d , &n);     ++n;     for (i = 0; i < n - 1; ++i) {       scanf( %d %c , &parent[i + 1], &w[i + 1]);       adj[parent[i + 1]].push_back(i + 1);     }     scanf( %d , &m);     for (i = 0; i < m; ++i) {       int x;       scanf( %d , &x);       mark[x] = true;       vec.push_back(x);     }   }   bool cmp(int lhs, int rhs) { return w[lhs] < w[rhs]; }   void dfs(int src) {     int i, j;     sbtr[src] += mark[src];     long long int sum = 0;     for (i = 0; i < adj[src].size(); ++i) {       int u = adj[src][i];       dfs(u);       cost[u] = sum;       sbtr[src] += sbtr[u];       sum += sbtr[u];     }   }   void make_tree(int lo, int hi, int iter) {     int mid = (lo + hi) >> 1;     if (lo == hi) {       tree[iter] = 100000000000, lz[iter] = 0;       return;     } else if (lo < hi) {       tree[iter] = 100000000000, lz[iter] = 0;       make_tree(lo, mid, 2 * iter + 1);       make_tree(mid + 1, hi, 2 * iter + 2);     }   }   void mrg(int iter) { tree[iter] = min(tree[2 * iter + 1], tree[2 * iter + 2]); }   void lazy_up(int iter, long long int v) {     tree[iter] += v;     lz[iter] += v;   }   void push_down(int iter) {     lazy_up(2 * iter + 1, lz[iter]);     lazy_up(2 * iter + 2, lz[iter]);     lz[iter] = 0;   }   void point_update(int lo, int hi, int iter, int idx, long long int v) {     int mid = (lo + hi) >> 1;     if (lo == hi) {       tree[iter] = v;       return;     }     push_down(iter);     if (idx >= lo && idx <= mid) {       point_update(lo, mid, 2 * iter + 1, idx, v);     } else {       point_update(mid + 1, hi, 2 * iter + 2, idx, v);     }     mrg(iter);   }   void range_update(int lo, int hi, int iter, int l, int r, long long int v) {     int mid = (lo + hi) >> 1;     if (l > r) {       return;     }     if (l <= lo && r >= hi) {       lazy_up(iter, v);       return;     }     push_down(iter);     if (l >= lo && r <= mid) {       range_update(lo, mid, 2 * iter + 1, l, r, v);     } else if (l >= mid + 1 && r <= hi) {       range_update(mid + 1, hi, 2 * iter + 2, l, r, v);     } else {       range_update(lo, mid, 2 * iter + 2, l, mid, v);       range_update(mid + 1, hi, 2 * iter + 2, mid + 1, r, v);     }     mrg(iter);   }   void F(int src) {     int i, j;     if (src) {       point_update(0, n - 1, 0, src, dp[parent[src]]);       range_update(0, n - 1, 0, 0, n, cost[src] + mark[parent[src]]);       if (mark[src]) {         dp[src] = min(tree[0] + 1, dp[parent[src]] + 1);       } else {         dp[src] = dp[parent[src]] + 1;       }     }     for (i = 0; i < adj[src].size(); ++i) {       int u = adj[src][i];       F(u);     }     if (src) {       point_update(0, n - 1, 0, src, 100000000000);       range_update(0, n - 1, 0, 0, n, -(cost[src] + mark[parent[src]]));     }   }   void solve() {     int i, j;     for (i = 0; i < n; ++i) {       sort(adj[i].begin(), adj[i].end(), cmp);     }     dfs(0);     make_tree(0, n - 1, 0);     dp[0] = 0, F(0);     for (i = 0; i < vec.size(); ++i) {       if (i) {         printf(   );       }       printf( %lld , dp[vec[i]]);     }     puts(  );   }   int main() {     input();     solve();   }