#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; (i) < (int)(n); ++ (i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++ (i))
#define ALL(x) begin(x), end(x)
using namespace std;
template <class T> inline void chmax(T & a, T const & b) { a = max(a, b); }

int main() {
    // input
    int n; cin >> n;
    vector<int> parent(n, -1);
    vector<vector<int> > children(n);
    REP3 (x, 1, n) {
        cin >> parent[x];
        children[parent[x]].push_back(x);
    }
    vector<int> a(n);
    REP (x, n) {
        cin >> a[x];
    }

    // solve
    constexpr int root = 0;

    auto get_leaf = [&](int x) {
        while (not children[x].empty()) {
            x = children[x].back();
        }
        return x;
    };

    auto cut_leaves = [&](int x) {
        while (x != root and a[x] == x and children[x].empty()) {
            int y = parent[x];
            auto it = find(ALL(children[y]), x);
            children[y].erase(it);
            x = y;
        }
    };
    REP (x, n) {
        cut_leaves(x);
    }

    vector<bool> is_leafish(n);
    auto update_leafish = [&](int x) {
        while (children[x].empty() or (children[x].size() == 1 and is_leafish[children[x][0]])) {
            is_leafish[x] = true;
            if (x == root) {
                break;
            } else {
                x = parent[x];
            }
        }
    };
    REP (x, n) {
        update_leafish(x);
    }

    vector<int> lookup(n);  // lookup : a_x |-> x
    REP (x, n) {
        lookup[a[x]] = x;
    }

    vector<int> ops;
    auto op = [&](int x) {
        assert (x != -1);
        assert (not (a[x] == x and children[x].empty()));
        ops.push_back(x);
        int last = a[root];
        for (int y = x; y != -1; y = parent[y]) {
            swap(a[y], last);
            lookup[a[y]] = y;
        }
        if (children[x].empty()) {
            cut_leaves(x);
            update_leafish(x);
        }
    };

    auto get_deepest_leafish_value = [&]() {
        vector<bool> is_fixed(n);
        function<void (int)> go1 = [&](int x) {
            if (is_leafish[x]) {
                vector<int> path;
                for (int y = x; ; ) {
                    path.push_back(y);
                    if (children[y].empty()) {
                        break;
                    } else {
                        y = children[y][0];
                    }
                }
                auto it = find(ALL(path), lookup[x]);
                if (it != path.end()) {
                    bool pred = true;
                    for (int i = 0; it + i != path.end(); ++ i) {
                        if (a[*(it + i)] != path[i]) {
                            pred = false;
                            break;
                        }
                    }
                    for (int i = 0; it + i != path.end(); ++ i) {
                        is_fixed[a[*(it + i)]] = true;
                    }
                }
            } else {
                for (int y : children[x]) {
                    go1(y);
                }
            }
        };
        go1(root);

        auto result = make_pair(-1, -1);
        function<void (int, int)> go2 = [&](int x, int depth) {
            if (is_leafish[a[x]] and not is_fixed[a[x]]) {
                chmax(result, make_pair(depth, a[x]));
            }
            for (int y : children[x]) {
                go2(y, depth + 1);
            }
        };
        go2(root, 0);
        return result.second;
    };

    while (not children[root].empty()) {
        int x = a[root];
        if (is_leafish[x]) {
            if (x == root or not is_leafish[parent[x]]) {
                op(get_leaf(x));
            } else {
                op(lookup[parent[x]]);
            }
        } else {
            op(lookup[get_deepest_leafish_value()]);
        }
    }

    // output
    cout << ops.size() << endl;
    for (int op : ops) {
        cout << op << endl;
    }
    assert (is_sorted(ALL(a)));
    assert (ops.size() <= 25000 * n / 2000);
    return 0;
}


Measured memory_bytes: 768