#ifdef DBG1
  #define LOCAL
#endif

#ifdef LOCAL
  #define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

#ifdef DBG1
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;

const int MAX_OPERS = 25000;

bool isGood(const vector <int> & a) {
  for (int i = 0; i < int(a.size()); ++i) {
    if (i != a[i]) {
      return false;
    }
  }
  return true;
}

void rotateToRoot(int v, vector <int> & a, const vector <int> & par) {
  if (v == 0) { return; }
  rotateToRoot(par[v], a, par);
  a[par[v]] = a[v];
}

void makeMove(vector <int> & opers, vector <int> & a, const vector <int> & par, int num) {
  opers.push_back(num);
  int tmp = a[0];
  rotateToRoot(num, a, par);
  a[num] = tmp;
}

bool is_parent(int u, int v, const vector<int> & inT, const vector<int> & outT) {
  return inT[u] <= inT[v] && outT[v] <= outT[u];
}

struct Move {
  int depth, v;
  bool ok;

  bool operator < (const Move & o) const {
    if (depth != o.depth) {
      return depth < o.depth;
    }
    return v < o.v;
  }
};

Move dfs2(int s, int dep, const vector <int> & a, const vector <vector<int>> & child, const vector<int> & inT, const vector <int> & outT) {
  if (child[s].empty()) {
    bool ok = is_parent(a[s], s, inT, outT) && is_parent(a[0], a[s], inT, outT);
    Move res = Move({dep, s, ok});
    dbg("s %d returns %d %d %d\n", s, res.depth, res.v, res.ok ? 1 : 0);
    return res;
  }

  Move res({-1, -1, true});
  bool ok = 1;
  for (int v : child[s]) {
    Move cur = dfs2(v, dep + 1, a, child, inT, outT);
    if (!is_parent(a[0], a[v], inT, outT)) {
      res.ok = false;
      res = max(res, Move({dep, v, false}));
    }
    if (!is_parent(a[s], a[v], inT, outT) && res.ok) {
      res.ok = 0;
      res = max(res, Move({dep, s, false}));
    }
    if (!cur.ok) {
      res.ok = false;
      res = max(res, cur);
    }
  }
  if (res.ok) {
    res = Move({dep, s, true});
  }

  if (!is_parent(res.v, a[res.v], inT, outT) && !is_parent(a[res.v], res.v, inT, outT)) {
    res.depth += int(a.size());
  }
  dbg("s %d returns %d %d %d\n", s, res.depth, res.v, res.ok ? 1 : 0);
  return res;
}

Move findMove(const vector<int> & a, const vector <vector<int>> & child, const vector<int> & inT, const vector<int> & outT) {
  return dfs2(a[0], 0, a, child, inT, outT);
}

void dfs(int v, const vector <vector<int>> & child, vector<int> & inT, vector <int> & outT, int &timer) {
  inT[v] = ++timer;
  for (int u : child[v]) {
    dfs(u, child, inT, outT, timer);
  }
  outT[v] = ++timer;
}

bool solve() {
  int n;
  if (scanf("%d", &n) != 1) { return false; }
  vector <vector<int>> child(n);
  vector <int> par(n, -1);
  for (int i = 1; i < n; ++i) {
    scanf("%d", &par[i]);
    child[par[i]].push_back(i);
  }
  vector <int> a(n);
  for (int i = 0; i < n; ++i) {
    scanf("%d", &a[i]);
  }

  vector <int> inT(n), outT(n);
  int timer = 0;
  dfs(0, child, inT, outT, timer);

  vector <int> opers;
  while (!isGood(a)) {
  #if 1
    if (n <= 30) {
      dbg("arr ");
      for (int x : a) {
        dbg("%d ", x);
      }
      dbg("\n");
    }
  #endif
    assert(int(opers.size()) < MAX_OPERS);
    Move move = findMove(a, child, inT, outT);
    dbg("move = %d %d %d\n", move.depth, move.v, move.ok ? 1 : 0);
    assert(move.v != 0);
    makeMove(opers, a, par, move.v);
  }
  printf("%d\n", int(opers.size()));
  for (int x : opers) {
    printf("%d\n", x);
  }
  return true;
}

int main() {
  while (solve());
  return 0;
}

Measured memory_bytes: 768