Problem:
Score : 2000 points

Problem Statement

You are given a rooted tree with N vertices.
The vertices are numbered 0, 1, ..., N-1.
The root is Vertex 0, and the parent of Vertex i (i = 1, 2, ..., N-1) is Vertex p_i.

Initially, an integer a_i is written in Vertex i.
Here, (a_0, a_1, ..., a_{N-1}) is a permutation of (0, 1, ..., N-1).

You can execute the following operation at most 25 000 times. Do it so that the value written in Vertex i becomes i.

Choose a vertex and call it v. Consider the path connecting Vertex 0 and v.

Rotate the values written on the path. That is, For each edge (i, p_i) along the path, replace the value written in Vertex p_i with the value written in Vertex i (just before this operation), and replace the value of v with the value written in Vertex 0 (just before this operation).

You may choose Vertex 0, in which case the operation does nothing.

Constraints

2 \leq N \leq 2000

0 \leq p_i \leq i-1

(a_0, a_1, ..., a_{N-1}) is a permutation of (0, 1, ..., N-1).

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 ... p_{N-1}
a_0 a_1 ... a_{N-1}

Output

In the first line, print the number of operations, Q.
In the second through (Q+1)-th lines, print the chosen vertices in order.

Sample Input 1

5
0 1 2 3
2 4 0 1 3

Sample Output 1

2
3
4

After the first operation, the values written in Vertex 0, 1, .., 4 are 4, 0, 1, 2, 3.

Sample Input 2

5
0 1 2 2
4 3 1 2 0

Sample Output 2

3
4
3
1

After the first operation, the values written in Vertex 0, 1, .., 4 are 3, 1, 0, 2, 4.

After the second operation, the values written in Vertex 0, 1, .., 4 are 1, 0, 2, 3, 4.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Globalization;
using System.Diagnostics;



class Myon
{
    public Myon() { }
    public static int Main()
    {
        new Myon().calc();
        return 0;
    }


    Scanner cin;


    int N;
    List<int>[] es;
    int[] p;
    int[] depth;
    int[,] LCA;
    bool[,] on;

    List<int> target;
    int[] rtarget;
    int targetpos = 0;
    int t2 = 0;
    XRand rnd = new XRand();

    List<int> ansList = new List<int>();
    void calc()
    {
        cin = new Scanner();
        N = cin.nextInt();
        p = new int[N];
        p[0] = -1;

        target = new List<int>();
        depth = new int[N];
        es = new List<int>[N];
        for (int i = 0; i < N; i++)
        {
            es[i] = new List<int>();
        }

        for (int i = 1; i < N; i++)
        {
            //randomtest
            //p[i] = rnd.nextInt(i);
            //Console.Write(p[i] + " ");
            p[i] = cin.nextInt();
            depth[i] = depth[p[i]] + 1;
            es[p[i]].Add(i);
        }
        pos = new int[N];
        rpos = new int[N];

        int[] ar = new int[N];
        for (int i = 0; i < N; i++)
        {
            ar[i] = i;
        }
        randomshuffle(ar);

        for (int i = 0; i < N; i++)
        {
            //randomtest
            //set(i, ar[i]);
            set(i, cin.nextInt());
        }

        rtarget = new int[N];
        dfs(0);
        LCA = new int[N, N];
        on = new bool[N, N];
        dfs2(0);

        //Console.WriteLine(string.Join(" ", target));

        while (!check())
        {
            //Console.WriteLine(string.Join(" ", pos) + "    " + targetpos + " " + t2);
            //Console.ReadLine();

            int firstTarget = target[t2];
            bool t2ok = true;
            
            int fpos = rpos[firstTarget];
            int lastpos = fpos;
            int now = p[fpos];
            while(now != -1)
            {
                int num = pos[now];
                int tnum = rtarget[num];

                if (tnum < t2)
                {
                    if (LCA[fpos, num] == now && !on[fpos, num] && !on[num, fpos])
                    {
                        //Console.WriteLine("NG because " + num + " " + lastpos + " " + now);
                        lastpos = now;
                        t2ok = false;
                    }
                }
                now = p[now];
            }

            if (!t2ok)
            {
                while (true)
                {
                    int me = pos[lastpos];
                    int tnum = rtarget[me];
                    if (tnum >= t2) break;
                    foreach (var next in es[lastpos])
                    {
                        if(on[me, next] || on[next, me])
                        {
                            lastpos = next;
                            break;
                        }
                    }
                }
            }

            //Console.WriteLine("move: " + lastpos + " " + firstTarget + " " + t2ok);
            move(lastpos);
            ansList.Add(lastpos);
            if (t2ok) t2++;
        }
        Console.WriteLine(ansList.Count);
        foreach (var item in ansList)
        {
            Console.WriteLine(item);
        }
    }

    void dfs(int a)
    {
        foreach (var next in es[a])
        {
            dfs(next);
        }
        rtarget[a] = target.Count;
        target.Add(a);
    }

    List<int> dfs2(int a)
    {
        List<int> ret = new List<int>();
        ret.Add(a);
        LCA[a, a] = a;
        on[a, a] = true;
        foreach (var next in es[a])
        {
            var l = dfs2(next);
            foreach (var b in l)
            {
                foreach (var c in ret)
                {
                    LCA[b, c] = LCA[c, b] = a;
                }
                on[a, b] = true;
            }
            foreach (var b in l) ret.Add(b);
        }
        return ret;
    }

    bool check()
    {
        while(targetpos < N)
        {
            if (pos[target[targetpos]] == target[targetpos]) targetpos++;
            else
            {
                t2 = Math.Max(t2, targetpos);
                return false;
            }
        }
        return true;
    }

    bool onRail(int mid, int last)
    {
        return on[last, mid];
    }
    

    int[] pos; // pos -> a
    int[] rpos; // a -> pos
    void set(int p, int a)
    {
        pos[p] = a;
        rpos[a] = p;
    }

    void move(int start)
    {
        int v = pos[start];
        int now = start;
        while(now != 0)
        {
            set(now, pos[p[now]]);
            now = p[now];
        }
        pos[0] = v;
    }

    //配列のランダム並び替え
    void randomshuffle<T>(T[] a)
    {
        int len = a.Length;
        for (int i = 0; i < len - 1; i++)
        {
            swap(ref a[i], ref a[i + rnd.nextInt(len - i)]);
        }
    }

    //swap
    void swap<T>(ref T a, ref T b)
    {
        T c = a;
        a = b;
        b = c;
    } 

}

class XRand
{
    uint x, y, z, w;


    public XRand()
    {
        init();
    }

    public XRand(uint s)
    {
        init();
        init_xor128(s);
    }

    void init()
    {
        x = 314159265; y = 358979323; z = 846264338; w = 327950288;

    }

    public void init_xor128(uint s)
    {
        z ^= s;
        z ^= z >> 21; z ^= z << 35; z ^= z >> 4;
        z *= 736338717;
    }

    uint next()
    {
        uint t = x ^ x << 11; x = y; y = z; z = w; return w = w ^ w >> 19 ^ t ^ t >> 8;
    }

    public long nextLong(long m)
    {
        return (long)((((ulong)next() << 32) + next()) % (ulong)m);
    }

    public int nextInt(int m)
    {
        return (int)(next() % m);
    }

    public int nextIntP(int a)
    {
        return (int)Math.Pow(a, nextDouble());
    }

    public int nextInt(int min, int max)
    {
        return min + nextInt(max - min + 1);
    }


    public double nextDouble()
    {
        return (double)next() / uint.MaxValue;
    }

    public double nextDoubleP(double a)
    {
        return Math.Pow(a, nextDouble());
    }
}


class Scanner
{
    string[] s;
    int i;

    char[] cs = new char[] { ' ' };

    public Scanner()
    {
        s = new string[0];
        i = 0;
    }

    public string next()
    {
        if (i < s.Length) return s[i++];
        string st = Console.ReadLine();
        while (st == "") st = Console.ReadLine();
        s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        if (s.Length == 0) return next();
        i = 0;
        return s[i++];
    }

    public int nextInt()
    {
        return int.Parse(next());
    }
    public int[] ArrayInt(int N, int add = 0)
    {
        int[] Array = new int[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextInt() + add;
        }
        return Array;
    }

    public long nextLong()
    {
        return long.Parse(next());
    }

    public long[] ArrayLong(int N, long add = 0)
    {
        long[] Array = new long[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextLong() + add;
        }
        return Array;
    }

    public double nextDouble()
    {
        return double.Parse(next());
    }


    public double[] ArrayDouble(int N, double add = 0)
    {
        double[] Array = new double[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextDouble() + add;
        }
        return Array;
    }
}