#ifdef LOCAL
#pragma optimize("", off)
#include "localstd1.h"
#else
#pragma GCC optimize("Ofast,unroll-loops")
#include <bits/allocator.h>
#pragma GCC target("avx2,bmi,bmi2")
#include <bits/stdc++.h>
#endif

using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;

#define all(a) (a).begin(), (a).end()

struct Node {
	vector<int> e;
	int s;
	int val = 0;
	int res = 0;
	int up = -1;

	int vers = -1;
};
vector<Node> graph;

struct segtree {
	struct Node {
		int mod = 0, mx = 0;
	};
	int sz = -1;
	vector<Node> tree;

	segtree(int n) {
		sz = 1 << __lg(n) + 2;
		tree.resize(sz);
	}

	void push(int u) {
		for (int a = u * 2; a < u * 2 + 2; a++) {
			tree[a].mod += tree[u].mod;
			tree[a].mx += tree[u].mod;
		}
		tree[u].mod = 0;
	}

	void upd(int u) {
		tree[u].mx = max(tree[u * 2].mx, tree[u * 2 + 1].mx);
	}

	void add(int l, int r, int x) {
		add(1, 0, sz / 2, l, r, x);
	}

	void add(int u, int l, int r, int ql, int qr, int x) {
		if (ql <= l && r <= qr) {
			tree[u].mod += x;
			tree[u].mx += x;
		}
		else if (r > ql && qr > l) {
			push(u);
			int mid = (l + r) / 2;
			add(u * 2, l, mid, ql, qr, x);
			add(u * 2 + 1, mid, r, ql, qr, x);
			upd(u);
		}
	}

	int get(int l, int r) {
		return get(1, 0, sz / 2, l, r);
	}

	int get(int u, int l, int r, int ql, int qr) {
		if (ql <= l && r <= qr) {
			return tree[u].mx;
		}
		else if (r > ql && qr > l) {
			push(u);
			int mid = (l + r) / 2;
			return max(get(u * 2, l, mid, ql, qr), get(u * 2 + 1, mid, r, ql, qr));
		}
		return 0;
	}
};

struct Hld {
	struct HldNode {
		int sz = 1, leader = -1, up = -1;
		int ind = -1;
		vector<int> e;
		int l = -1, r = -1;
	};
	vector<HldNode> tree;
	segtree segt;
	Hld() : segt(graph.size()) {
		int n = graph.size();
		tree.resize(n);
		for (int i = 0; i < n; i++) {
			tree[i].up = graph[i].up;
			tree[i].e = graph[i].e;
		}
		dfs_sz(0);
		int ind = 0;
		dfs_ind(0, 0, ind);
	}

	void dfs_sz(int u) {
		for (int to : tree[u].e) {
			dfs_sz(to);
			tree[u].sz += tree[to].sz;
		}
		sort(all(tree[u].e), [&](int l, int r) {return tree[l].sz < tree[r].sz; });
	}

	void dfs_ind(int u, int leader, int& ind) {
		tree[u].l = ind;
		tree[u].ind = ind++;
		tree[u].leader = leader;
		if (tree[u].e.size()) {
			dfs_ind(tree[u].e[0], leader, ind);
		}
		for (int i = 1; i < tree[u].e.size(); i++) {
			int to = tree[u].e[i];
			dfs_ind(to, to, ind);
		}
	}

	void add(int u, int x) {
		int cur = u;
		while (cur != -1) {
			int leader = tree[cur].leader;
			int l = tree[leader].l, r = tree[cur].ind + 1;
			segt.add(l, r, x);
			cur = tree[leader].up;
		}
	}

	int get_mx(int u) {
		vector<pair<int, int>> banned;
		int cur = u;
		while (cur != -1) {
			int leader = tree[cur].leader;
			int l = tree[leader].l, r = tree[cur].ind + 1;
			banned.push_back({ l, r });
			cur = tree[leader].up;
		}
		reverse(all(banned));
		int res = 0;
		int prev_r = 0;
		for (pair<int, int> seg : banned) {
			res = max(res, segt.get(prev_r, seg.first));
			prev_r = seg.second;
		}
		res = max(res, segt.get(prev_r, tree.size()));
		return res;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, q; cin >> n >> q;
	graph.assign(n, { });
	for (int i = 1; i < n; i++) {
		int p; cin >> p; p--;
		graph[p].e.push_back(i);
		graph[i].up = p;
	}
	for (int i = 0; i < n; i++) {
		cin >> graph[i].s;
	}
	Hld hld;

	priority_queue<pair<int, int>> bfs;
	bfs.push({ graph[0].s, 0 });
	int cnt = 0;
	while (bfs.size()) {
		auto [s, u] = bfs.top();
		bfs.pop();
		hld.add(u, 1);
		graph[u].res = cnt;
		int mx_ec = hld.get_mx(u);
		graph[u].res -= mx_ec;
		cnt++;
		for (int to : graph[u].e) {
			bfs.push({ graph[to].s, to });
		}
	}

	while (q--) {
		int u; cin >> u; u--;
		cout << graph[u].res << '\n';
	}
	
	return 0;
}