#ifdef LOCAL
#define _GLIBCXX_DEBUG
#define debug(x) cerr << __LINE__ << ": " << (#x) << " = " << (x) << endl
#else
#define debug(...) 42
#endif

#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
// #pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef __int128 LL;
#define all(x) (x).begin(), (x).end()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

template<typename T>
istream &operator >>(istream &in, vector<T> &a) {
    for (auto &elem : a) {
        in >> elem;
    }
    return in;
}

template<typename T>
ostream &operator <<(ostream &out, const vector<T> &a) {
    for (const auto &elem : a) {
        out << elem << ' ';
    }
    return out;
}

#ifdef LOCAL
constexpr int N = 1 << 9;
#else
constexpr int N = 1 << 19;
#endif

class SegmentTree {
    int n;
    int st[2 * N]{}, mod[2 * N]{};

    void push(int v) {
        if (!mod[v]) {
            return;
        }
        st[v * 2] += mod[v];
        mod[v * 2] += mod[v];
        st[v * 2 + 1] += mod[v];
        mod[v * 2 + 1] += mod[v];
        mod[v] = 0;
    }

    void update(int v, int tl, int tr, int ql, int qr, int x) {
        if (qr <= tl || tr <= ql) {
            return;
        }
        if (ql <= tl && tr <= qr) {
            st[v] += x;
            mod[v] += x;
            return;
        }
        push(v);
        int tm = (tl + tr) / 2;
        update(v * 2, tl, tm, ql, qr, x);
        update(v * 2 + 1, tm, tr, ql, qr, x);
        st[v] = max(st[v * 2], st[v * 2 + 1]);
    }

public:
    explicit SegmentTree(int n) {
        this->n = n;
    }

    void update(int ql, int qr, int x) {
        update(1, 0, n, ql, qr, x);
    }

    ll get() {
        return st[1];
    }
};

int n, q;
vector<int> g[N], req;
int s[N], tin[N], tout[N];
int sz[N], head[N], par[N];

int size_dfs(int v) {
    sz[v] = 1;
    for (int u : g[v]) {
        sz[v] += size_dfs(u);
    }
    return sz[v];
}

void heavy_dfs(int v, int &timer, int _head) {
    tin[v] = timer++;
    head[v] = _head;
    if (!g[v].empty()) {
        for (int i = 1; i < g[v].size(); ++i) {
            if (sz[g[v][i]] > sz[g[v][0]]) {
                swap(g[v][i], g[v][0]);
            }
        }
        heavy_dfs(g[v][0], timer, _head);
        for (int i = 1; i < g[v].size(); ++i) {
            heavy_dfs(g[v][i], timer, g[v][i]);
        }
    }
    tout[v] = timer;
}

void solve() {
    {
        size_dfs(1);
        int timer = 0;
        heavy_dfs(1, timer, 1);
    }
    vector<int> order(n);
    iota(all(order), 1);
    sort(all(order), [](int u, int v){return s[u] < s[v];});
    SegmentTree st(n + 1);
    for (int v = 1; v <= n; ++v) {
        st.update(tin[v], tin[v] + 1, sz[v]);
    }

    auto add_on_path = [&](int v, int x) {
        while (v) {
            st.update(tin[head[v]], tin[v] + 1, x);
            v = par[head[v]];
        }
    };

    vector<int> res(n + 1);
    int rem = n;
    for (int v : order) {
        add_on_path(v, -1e7);
        st.update(tin[v], tout[v], -1e7);
        int x = st.get();
        rem--;
        res[v] = v == 1 ? 0 : max(rem - max(x, 0), 1);
        st.update(tin[v], tout[v], 1e7);
        add_on_path(v, 1e7 - 1);
    }
    for (int v : req) {
        cout << res[v] << ' ';
    }
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> q;
    for (int v = 2; v <= n; ++v) {
        cin >> par[v];
        g[par[v]].push_back(v);
    }
    for (int v = 1; v <= n; ++v) {
        cin >> s[v];
    }
    req.resize(q);
    cin >> req;
    solve();
}