#ifndef LOCAL
  #pragma GCC optimize("Ofast,unroll-loops")
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#ifndef LOCAL
  #pragma GCC target("avx,avx2,fma")
#endif

using namespace std;
using namespace __gnu_pbds;

using ll = long long;

constexpr int buffer_size = 1 << 20;
constexpr char my_flush = '@';

char read_char() {
  static char cache[buffer_size];
  static int pos = 0;
  static int sz = 0;
  if (pos == sz) {
    sz = fread(cache, 1, buffer_size, stdin);
    pos = 0;
  }
  if (pos == sz) {
    return EOF;
  }
  return cache[pos++];
}

void write_char(char c) {
  static char cache[buffer_size];
  static int pos = 0;
  if (pos == buffer_size || c == my_flush) {
    fwrite(cache, 1, pos, stdout);
    pos = 0;
  }
  if (c != my_flush) {
    cache[pos++] = c;
  }
}

template<typename T>
void write_num(T x) {
  char st[64];
  int pos = 0;
  if (x < 0) {
    write_char('-');
    x = -x;
  }
  do {
    st[pos++] = char('0' + x % 10);
    x /= 10;
  } while (x > 0);
  while (pos > 0) {
    write_char(st[--pos]);
  }
}

template<typename T>
T read_num() {
  bool sign = false;
  char c;
  T res = 0;
  for (;;) {
    c = read_char();
    if (c == '-') {
      sign = true;
    }
    if (!isdigit(c)) {
      break;
    }
    res = res * 10 + (c - '0');
  }
  return res;
}

string read_str() {
  string ans;
  char c;
  for (;;) {
    c = read_char();
    if (isalnum(c) || isgraph(c)) {
      ans.push_back(c);
    } else {
      break;
    }
  }
  return move(ans);
}

void print_str(const string& s) {
  for (auto c : s) {
    write_char(c);
  }
}

const int maxn = 3e1 + 1;

struct segtree {
  struct node {
    int mx, av, add;
    node* l;
    node* r;

    node(int v = 0) : mx(v), add(0), av(-1), l(0), r(0) {}

    node(node* n) : mx(n->mx), add(n->add), av(n->av), l(n->l), r(n->r) {}
  };

  int get_max(node* n) {
    return n ? n->mx : 0;
  }

  vector<node*> cache;
  int N;

  segtree(int n = 0) : N(n), cache{0} {}

  void apply_av(node* n, int av) {
    n->mx = n->av = av;
    n->add = 0;
  }

  void apply_add(node* n, int add) {
    n->mx += add;
    n->add += add;
  }

  node* push(node* n) {
    assert(n);
    if (!n->l) n->l = new node();
    n->l = new node(n->l);
    if (!n->r) n->r = new node();
    n->r = new node(n->r);
    if (n->av != -1) {
      apply_av(n->l, n->av);
      apply_av(n->r, n->av);
      n->av = -1;
    }
    if (n->add != 0) {
      apply_add(n->l, n->add);
      apply_add(n->r, n->add);
      n->add = 0;
    }
    return n;
  }

  void set(int lq, int rq) {
    cache.push_back(set(lq, rq, 0, N, cache.back()));
  }

  node* set(int lq, int rq, int lx, int rx, node* n) {
    if (rx <= lq || lx >= rq) return n;
    if (!n) n = new node();
    n = new node(n);
    if (lq <= lx && rx <= rq) {
      apply_av(n, 0);
      return n;
    }
    n = push(n);
    int m = (lx + rx) / 2;
    n->l = set(lq, rq, lx, m, n->l);
    n->r = set(lq, rq, m, rx, n->r);
    n->mx = max(n->l->mx, n->r->mx);
    return n;
  }

  void add(int lq, int rq) {
    cache.push_back(add(lq, rq, 0, N, cache.back()));
  }

  node* add(int lq, int rq, int lx, int rx, node* n) {
    if (rx <= lq || lx >= rq) return n;
    if (!n) n = new node();
    n = new node(n);
    if (lq <= lx && rx <= rq) {
      apply_add(n, 1);
      return n;
    }
    n = push(n);
    int m = (lx + rx) / 2;
    n->l = add(lq, rq, lx, m, n->l);
    n->r = add(lq, rq, m, rx, n->r);
    n->mx = max(n->l->mx, n->r->mx);
    return n;
  }

  int get() {
    return get_max(cache.back());
  }

  void rollback() {
    cache.pop_back();
  }
} st(maxn);

vector<int> g[maxn];
int p[maxn], tin[maxn], tout[maxn], s[maxn], ans[maxn], sz[maxn], head[maxn];
int n, q;
int tt = 0;

void dfs(int u = 1) {
  sz[u] = 1;
  for (int& v : g[u]) {
    dfs(v);
    sz[u] += sz[v];
    if (sz[v] > sz[g[u][0]]) {
      swap(v, g[u][0]);
    }
  }
}

void decomp(int u = 1, int h = 1) {
  tin[u] = tt++;
  head[u] = h;
  if (!g[u].empty()) {
    decomp(g[u][0], h);
  }
  for (int v : g[u]) {
    if (v == g[u][0]) {
      continue;
    }
    decomp(v, v);
  }
  tout[u] = tt;
}

int par_set(int u) {
  int cnt = 0;
  while (head[u] != 1) {
    st.set(tin[head[u]], tin[u] + 1);
    u = p[head[u]];
    ++cnt;
  }
  st.set(tin[1], tin[u] + 1);
  ++cnt;
  return cnt;
}

void par_add(int u) {
  while (head[u] != 1) {
    st.add(tin[head[u]], tin[u] + 1);
    u = p[head[u]];
  }
  st.add(tin[1], tin[u] + 1);
}

bool is_par(int u, int v) {
  return tin[u] <= tin[v] && tout[v] <= tout[u];
}

void solve() {
  cin >> n >> q;
  // n = read_num<int>();
  // q = read_num<int>();
  for (int i = 2; i <= n; ++i) {
    cin >> p[i];
    // p[i] = read_num<int>();
    g[p[i]].push_back(i);
  }
  for (int i = 1; i <= n; ++i) {
    cin >> s[i];
    // s[i] = read_num<int>();
  }
  dfs();
  decomp();
  vector<int> h;
  set<pair<int, int>, greater<>> val;
  val.emplace(s[1], 1);
  while (!val.empty()) {
    int u = val.begin()->second;
    h.push_back(u);
    val.erase(val.begin());
    for (int v : g[u]) {
      val.emplace(s[v], v);
    }
  }
  // set<pair<int, int>, greater<>> mx;
  // mx.emplace(0, 0);
  for (int i = 0; i < n; ++i) {
    // for (int j = h[i]; j; j = p[j]) {
    //   mx.erase({cnt[j], j});
    // }
    // ans[h[i]] = i - mx.begin()->first;
    // for (int j = h[i]; j; j = p[j]) {
    //   mx.insert({++cnt[j], j});
    // }
    int c = par_set(h[i]);
    ans[h[i]] = i - st.get();
    while (c --> 0) {
      st.rollback();
    }
    par_add(h[i]);
  }
  for (int i = 0; i < q; ++i) {
    int u;
    cin >> u;
    // u = read_num<int>();
    cout << ans[u] << ' ';
    // write_num(ans[u]);
    // write_char(' ');
  }
  cout << '\n';
  // write_char('\n');
}

signed main() {
  // freopen("in", "r", stdin);
  // cin.tie(0)->sync_with_stdio(0);
  int t = 1;
  // cin >> t;
  for (int i = 0; i < t; ++i) {
    solve();
  }
  write_char(my_flush);
}