#pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#ifdef LOCAL
    #define debug(x) cout << #x << ": " << x << endl;
#else
    #define debug(x)
#endif
#define mt_seed chrono::high_resolution_clock::now().time_since_epoch().count()
#define time_now chrono::high_resolution_clock::now()
#define time_res(s, f) chrono::duration_cast<chrono::nanoseconds>(f - s).count()
#define fast ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define file_in freopen("input.txt", "r", stdin);
#define file_out freopen("output.txt", "w", stdout);
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a.size())
#define pb push_back
#define ff first
#define sc second
// #define int ll

using namespace std;
using namespace __gnu_pbds;

using ld = long double;
using ll = long long;
using ull = unsigned long long;
using str = string;
using pii = pair<int, int>;
using ordered_set = tree<int, null_type, less<>, rb_tree_tag, tree_order_statistics_node_update>;

template<typename T1, typename T2> istream& operator>>(istream &in, pair<T1, T2> &a) { in >> a.ff >> a.sc; return in; }
#ifdef LOCAL
    template<typename T1, typename T2> ostream& operator<<(ostream &out, const pair<T1, T2> &a) { out << "{" << a.ff << ' ' << a.sc << "}"; return out; }
#else
    template<typename T1, typename T2> ostream& operator<<(ostream &out, const pair<T1, T2> &a) { out << a.ff << ' ' << a.sc; return out; }
#endif
template<typename T> istream& operator>>(istream &in, vector<T> &a) { for (auto &el : a) in >> el; return in; }
template<typename T> ostream& operator<<(ostream &out, const vector<T> &a) { for (auto &el : a) out << el << " "; return out; }
template<typename T> ostream& operator<<(ostream &out, const set<T> &a) { for (auto &el : a) out << el << " "; return out; }
template<typename T> ostream& operator<<(ostream &out, const multiset<T> &a) { for (auto &el : a) out << el << " "; return out; }
template<typename T, typename comp> ostream& operator<<(ostream &out, const unordered_set<T, comp> &a) { for (auto &el : a) out << el << " "; return out; }
template<typename T> T max(T a, T b, T c) { return max(a, max(b, c)); }
template<typename T> T max(T a, T b, T c, T d) { return max(max(a, b), max(c, d)); }
template<typename T> T min(T a, T b, T c) { return min(a, min(b, c)); }
template<typename T> T min(T a, T b, T c, T d) { return min(min(a, b), min(c, d)); }
const ll LOL = mt_seed;
mt19937_64 genom(LOL); ll randint(ll l, ll r) { uniform_int_distribution<ll> random_distrib_2_0(l, r); return random_distrib_2_0(genom); }
const ll RANDOM = genom(); struct chash { ll operator()(ll x) { return x ^ RANDOM; } };

const int N = 3e5;

vector<vector<int>> g;
int s[N];

vector<int> ord;
void getOrd() {
    ord.clear();
    set<pii> st;
    st.insert({-s[0], 0});
    while (!st.empty()) {
        int v = st.begin()->sc;
        ord.pb(v);
        st.erase(st.begin());
        for (auto to : g[v]) {
            st.insert({-s[to], to});
        }
    }
}

int preprecalc(int v) {
    int sz = 1, best = -1;
    for (auto &to : g[v]) {
        int sz_to = preprecalc(to);
        if (sz_to > best) {
            best = sz_to;
            swap(g[v][0], to);
        }
        sz += sz_to;
    }
    return sz;
}

int timer = 0;
int tin[N]{}, tout[N]{}, nx[N]{}, p[N]{};

void precalc(int v) {
    tin[v] = timer++;
    for (auto to : g[v]) {
        if (to == 0) {
            nx[to] = nx[v];
            precalc(to);
        } else {
            nx[to] = to;
            precalc(to);
        }
    }
    tout[v] = timer;
}

const int Nt = 1 << 20;

struct seg_tree {
    int n;
    // vector<int> mx, add;
    // vector<bool> bad;
    int mx[Nt]{}, add[Nt]{};
    bool bad[Nt]{};

    void resize(int _n) {
        n = _n;
        // mx.resize(4 * n);
        // add.resize(4 * n);
        // bad.resize(4 * n);
        // mx.resize(Nt);
        // add.resize(Nt);
        // bad.resize(Nt);
    }

    inline void calc(int id) {
        mx[id] = max(get(id * 2 + 1), get(id * 2 + 2));
    }
    inline void push(int id) {
        mx[id] += add[id];
        add[id * 2 + 1] += add[id];
        add[id * 2 + 2] += add[id];
        add[id] = 0;
    }
    inline int get(int id) {
        return bad[id] ? 0 : mx[id] + add[id];
    }

    void upd(int id, int l, int r, int lx, int rx, int x) {
        if (lx <= l && r <= rx) {
            add[id] += x;
            return;
        }
        if (r <= lx || rx <= l) return;
        push(id);
        upd(id * 2 + 1, l, (l + r) / 2, lx, rx, x);
        upd(id * 2 + 2, (l + r) / 2, r, lx, rx, x);
        calc(id);
    }
    void upd(int l, int r, int x) {
        upd(0, 0, n, l, r, x);
    }

    // int get(int id, int l, int r, int lx, int rx) {
    //     if (lx <= l && r <= rx) return get(id, l, r);
    //     if (r <= lx || rx <= l) return 0;
    //     push(id);
    //     return operation(get(id * 2 + 1, l, (l + r) / 2, lx, rx), get(id * 2 + 2, (l + r) / 2, r, lx, rx));
    // }
    // int get(int l, int r) {
    //     return get(0, 0, n, l, r);
    // }

    int getMax() { return get(0); }

    void set0(int id, int l, int r, int lx, int rx) {
        if (lx <= l && r <= rx) {
            bad[id] = 1;
            return;
        }
        if (r <= lx || rx <= l) return;
        push(id);
        set0(id * 2 + 1, l, (l + r) / 2, lx, rx);
        set0(id * 2 + 2, (l + r) / 2, r, lx, rx);
        calc(id);
    }
    void set0(int l, int r) { set0(0, 0, n, l, r); }

    void set1(int id, int l, int r, int lx, int rx) {
        if (lx <= l && r <= rx) {
            bad[id] = 0;
            return;
        }
        if (r <= lx || rx <= l) return;
        push(id);
        set1(id * 2 + 1, l, (l + r) / 2, lx, rx);
        set1(id * 2 + 2, (l + r) / 2, r, lx, rx);
        calc(id);
    }
    void set1(int l, int r) { set1(0, 0, n, l, r); }
} t;

signed main() {
    fast
#ifdef LOCAL
    file_in
#endif

    auto st = time_now;

    int n, q;
    cin >> n >> q;
    ord.reserve(n);
    // p.resize(n - 1);
    // tin.resize(n);
    // tout.resize(n);
    // nx.resize(n);
    // s.resize(n);
    // cin >> p >> s;

    p[0] = -1;
    for (int i = 1; i < n; ++i)
        cin >> p[i];
    for (int i = 0; i < n; ++i)
        cin >> s[i];

    for (auto &el : p) --el;

    g.resize(n);
    for (int i = 0; i < n - 1; ++i) {
        g[p[i + 1]].pb(i + 1);
    }

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    preprecalc(0);

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    precalc(0);

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    getOrd();

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    t.resize(n);

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    vector<int> ans(n);
    int id = -1;

    // cout << fixed << setprecision(10) << "\nPrecalc: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    for (auto v : ord) {
        ++id;
        int cur = v;
        while (cur >= 0) {
            t.set0(tin[nx[cur]], tin[cur] + 1);
            cur = p[nx[cur]];
        }

        ans[v] = id - t.getMax();

        cur = v;
        while (cur >= 0) {
            t.set1(tin[nx[cur]], tin[cur] + 1);
            cur = p[nx[cur]];
        }

        cur = v;
        while (cur >= 0) {
            t.upd(tin[nx[cur]], tin[cur] + 1, 1);
            cur = p[nx[cur]];
        }
    }

    // cout << fixed << setprecision(10) << "\nalmost_done: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    for (int i = 0; i < q; ++i) {
        int v;
        cin >> v;
        --v;

        cout << ans[v] << ' ';
    }

    // cout << fixed << setprecision(10) << "\nUsed: " << time_res(st, time_now) / 1e6 << " ms" << endl;

    return 0;
}
