Problem: You have two rooted undirected trees, each contains n vertices. Let's number the vertices of each tree with integers from 1 to n. The root of each tree is at vertex 1. The edges of the first tree are painted blue, the edges of the second one are painted red. For simplicity, let's say that the first tree is blue and the second tree is red.

Edge {x, y} is called bad for edge {p, q} if two conditions are fulfilled: 

  1. The color of edge {x, y} is different from the color of edge {p, q}. 
  2. Let's consider the tree of the same color that edge {p, q} is. Exactly one of vertices x, y lies both in the subtree of vertex p and in the subtree of vertex q. 



In this problem, your task is to simulate the process described below. The process consists of several stages:

  1. On each stage edges of exactly one color are deleted. 
  2. On the first stage, exactly one blue edge is deleted. 
  3. Let's assume that at the stage i we've deleted edges {u1, v1}, {u2, v2}, ..., {uk, vk}. At the stage i + 1 we will delete all undeleted bad edges for edge {u1, v1}, then we will delete all undeleted bad edges for edge {u2, v2} and so on until we reach edge {uk, vk}. 



For each stage of deleting edges determine what edges will be removed on the stage. Note that the definition of a bad edge always considers the initial tree before it had any edges removed.

Input

The first line contains integer n (2 ≤ n ≤ 2·105) — the number of vertices in each tree.

The next line contains n - 1 positive integers a2, a3, ..., an (1 ≤ ai ≤ n; ai ≠ i) — the description of edges of the first tree. Number ai means that the first tree has an edge connecting vertex ai and vertex i.

The next line contains n - 1 positive integers b2, b3, ..., bn (1 ≤ bi ≤ n; bi ≠ i) — the description of the edges of the second tree. Number bi means that the second tree has an edge connecting vertex bi and vertex i. 

The next line contains integer idx (1 ≤ idx < n) — the index of the blue edge that was removed on the first stage. Assume that the edges of each tree are numbered with numbers from 1 to n - 1 in the order in which they are given in the input. 

Output

For each stage of removing edges print its description. Each description must consist of exactly two lines. If this is the stage when blue edges are deleted, then the first line of the description must contain word Blue, otherwise — word Red. In the second line print the indexes of the edges that will be deleted on this stage in the increasing order.

Examples

Input

5
1 1 1 1
4 2 1 1
3


Output

Blue
3
Red
1 3
Blue
1 2
Red
2

Note

For simplicity let's assume that all edges of the root tree received some direction, so that all vertices are reachable from vertex 1. Then a subtree of vertex v is a set of vertices reachable from vertex v in the resulting directed graph (vertex v is also included in the set).

Solution (in JAVA):

Solution:
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Random;
import java.util.ArrayList;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.List;
import java.io.Closeable;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            ETwoRootedTrees solver = new ETwoRootedTrees();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class ETwoRootedTrees {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.ri();
            Edge[] blueE = new Edge[n - 1];
            Edge[] redE = new Edge[n - 1];
            HeavyLightDecompose blueT = new HeavyLightDecompose(n, 0);
            HeavyLightDecompose redT = new HeavyLightDecompose(n, 0);

            for (int i = 0; i < n - 1; i++) {
                Edge e = new Edge();
                e.a = in.ri() - 1;
                e.b = i + 1;
                e.id = i;
                blueE[i] = e;
                blueT.addEdge(e.a, e.b);
            }

            for (int i = 0; i < n - 1; i++) {
                Edge e = new Edge();
                e.a = in.ri() - 1;
                e.b = i + 1;
                e.id = i;
                redE[i] = e;
                redT.addEdge(e.a, e.b);
            }

            blueT.finish();
            redT.finish();

            for (Edge e : redE) {
                blueT.processPath(e.a, e.b, e);
            }
            for (Edge e : blueE) {
                redT.processPath(e.a, e.b, e);
            }

            List<Edge> dq = new ArrayList<>(n * 20);
            List<Edge> buf = new ArrayList<>(n * 20);
            dq.add(blueE[in.ri() - 1]);
            dq.get(0).visited = true;
            boolean blue = true;
            IntegerArrayList sorted = new IntegerArrayList(n);
            while (!dq.isEmpty()) {
                buf.clear();
                sorted.clear();
                if (blue) {
                    out.println("Blue");
                    for (Edge e : dq) {
                        sorted.add(e.id);
                        int child = blueT.child(e);
                        blueT.consume(child, buf);
                    }
                } else {
                    out.println("Red");
                    for (Edge e : dq) {
                        sorted.add(e.id);
                        int child = redT.child(e);
                        redT.consume(child, buf);
                    }
                }
                sorted.sort();
                for (int i = 0; i < sorted.size(); i++) {
                    out.append(sorted.get(i) + 1).append(' ');
                }
                out.println();
                blue = !blue;
                List<Edge> tmp = dq;
                dq = buf;
                buf = tmp;
            }
        }

    }

    static class IntegerArrayList implements Cloneable {
        private int size;
        private int cap;
        private int[] data;
        private static final int[] EMPTY = new int[0];

        public IntegerArrayList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new int[cap];
            }
        }

        public IntegerArrayList(int[] data) {
            this(0);
            addAll(data);
        }

        public IntegerArrayList(IntegerArrayList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public IntegerArrayList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException("Access [" + i + "]");
            }
        }

        public int get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(int x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(int[] x) {
            addAll(x, 0, x.length);
        }

        public void addAll(int[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(IntegerArrayList list) {
            addAll(list.data, 0, list.size);
        }

        public void sort() {
            if (size <= 1) {
                return;
            }
            Randomized.shuffle(data, 0, size);
            Arrays.sort(data, 0, size);
        }

        public int size() {
            return size;
        }

        public int[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof IntegerArrayList)) {
                return false;
            }
            IntegerArrayList other = (IntegerArrayList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Integer.hashCode(data[i]);
            }
            return h;
        }

        public IntegerArrayList clone() {
            IntegerArrayList ans = new IntegerArrayList();
            ans.addAll(this);
            return ans;
        }

    }

    static class Randomized {
        public static void shuffle(int[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                int tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static int nextInt(int l, int r) {
            return RandomWrapper.INSTANCE.nextInt(l, r);
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int ri() {
            return readInt();
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int floorAverage(int x, int y) {
            return (x & y) + ((x ^ y) >> 1);
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private static final int THRESHOLD = 32 << 10;
        private final Writer os;
        private StringBuilder cache = new StringBuilder(THRESHOLD * 2);

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        private void afterWrite() {
            if (cache.length() < THRESHOLD) {
                return;
            }
            flush();
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput append(String c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput println(String c) {
            return append(c).println();
        }

        public FastOutput println() {
            return append('\n');
        }

        public FastOutput flush() {
            try {
//            boolean success = false;
//            if (stringBuilderValueField != null) {
//                try {
//                    char[] value = (char[]) stringBuilderValueField.get(cache);
//                    os.write(value, 0, cache.length());
//                    success = true;
//                } catch (Exception e) {
//                }
//            }
//            if (!success) {
                os.append(cache);
//            }
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class SequenceUtils {
        public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class HeavyLightDecompose {
        int n;
        int order = 1;
        HeavyLightDecompose.HLDNode root;
        HeavyLightDecompose.HLDNode[] nodes;
        HeavyLightDecompose.HLDNode[] segIndexToNode;
        HeavyLightDecompose.Segment segment;

        public int child(Edge e) {
            HeavyLightDecompose.HLDNode a = nodes[e.a];
            HeavyLightDecompose.HLDNode b = nodes[e.b];
            return a.father == b ? a.id : b.id;
        }

        public HeavyLightDecompose(int n, int rootId) {
            this.n = n;
            nodes = new HeavyLightDecompose.HLDNode[n];
            for (int i = 0; i < n; i++) {
                nodes[i] = new HeavyLightDecompose.HLDNode();
                nodes[i].id = i;
            }
            root = nodes[rootId];
        }

        public void addEdge(int a, int b) {
            nodes[a].next.add(nodes[b]);
            nodes[b].next.add(nodes[a]);
        }

        public void finish() {
            dfs(root, null);
            dfs2(root, root);
            segIndexToNode = new HeavyLightDecompose.HLDNode[n + 1];
            for (int i = 0; i < n; i++) {
                segIndexToNode[nodes[i].dfsOrderFrom] = nodes[i];
            }
            segment = new HeavyLightDecompose.Segment(1, n);
        }

        public void consume(int nodeId, List<Edge> consumer) {
            HeavyLightDecompose.HLDNode node = nodes[nodeId];
            segment.query(node.dfsOrderFrom, node.dfsOrderFrom, 1, n, consumer);
        }

        public void processPath(int uId, int vId, Edge e) {
            HeavyLightDecompose.HLDNode u = nodes[uId];
            HeavyLightDecompose.HLDNode v = nodes[vId];
            while (u != v) {
                if (u.link == v.link) {
                    if (u.size > v.size) {
                        HeavyLightDecompose.HLDNode tmp = u;
                        u = v;
                        v = tmp;
                    }
                    segment.update(v.dfsOrderFrom + 1, u.dfsOrderFrom, 1, n, e);
                    u = v;
                } else {
                    if (u.link.size > v.link.size) {
                        HeavyLightDecompose.HLDNode tmp = u;
                        u = v;
                        v = tmp;
                    }
                    segment.update(u.link.dfsOrderFrom, u.dfsOrderFrom, 1, n, e);
                    u = u.link.father;
                }
            }
        }

        private static void dfs(HeavyLightDecompose.HLDNode root, HeavyLightDecompose.HLDNode father) {
            root.size = 1;
            root.father = father;
            for (HeavyLightDecompose.HLDNode node : root.next) {
                if (node == father) {
                    continue;
                }
                dfs(node, root);
                root.size += node.size;
                if (root.heavy == null || root.heavy.size < node.size) {
                    root.heavy = node;
                }
            }
        }

        private void dfs2(HeavyLightDecompose.HLDNode root, HeavyLightDecompose.HLDNode link) {
            root.dfsOrderFrom = order++;
            root.link = link;
            if (root.heavy != null) {
                dfs2(root.heavy, link);
            }
            for (HeavyLightDecompose.HLDNode node : root.next) {
                if (node == root.father || node == root.heavy) {
                    continue;
                }
                dfs2(node, node);
            }
            root.dfsOrderTo = order - 1;
        }

        public static class Segment implements Cloneable {
            private HeavyLightDecompose.Segment left;
            private HeavyLightDecompose.Segment right;
            private List<Edge> edges = new ArrayList<>();

            public void pushUp() {
            }

            public void modify(Edge e) {
                edges.add(e);
            }

            public void pushDown() {
            }

            public Segment(int l, int r) {
                if (l < r) {
                    int m = DigitUtils.floorAverage(l, r);
                    left = new HeavyLightDecompose.Segment(l, m);
                    right = new HeavyLightDecompose.Segment(m + 1, r);
                    pushUp();
                } else {
                }
            }

            private boolean covered(int ll, int rr, int l, int r) {
                return ll <= l && rr >= r;
            }

            private boolean noIntersection(int ll, int rr, int l, int r) {
                return ll > r || rr < l;
            }

            public void update(int ll, int rr, int l, int r, Edge x) {
                if (noIntersection(ll, rr, l, r)) {
                    return;
                }
                if (covered(ll, rr, l, r)) {
                    modify(x);
                    return;
                }
                pushDown();
                int m = DigitUtils.floorAverage(l, r);
                left.update(ll, rr, l, m, x);
                right.update(ll, rr, m + 1, r, x);
                pushUp();
            }

            public void query(int ll, int rr, int l, int r, List<Edge> consumer) {
                if (noIntersection(ll, rr, l, r)) {
                    return;
                }
                if (!edges.isEmpty()) {
                    for (Edge e : edges) {
                        if (e.visited) {
                            continue;
                        }
                        e.visited = true;
                        consumer.add(e);
                    }
                    edges.clear();
                }
                if (l == r) {
                    return;
                }
                pushDown();
                int m = DigitUtils.floorAverage(l, r);
                left.query(ll, rr, l, m, consumer);
                right.query(ll, rr, m + 1, r, consumer);
            }

            private void toString(StringBuilder builder) {
                if (left == null && right == null) {
                    builder.append("val").append(",");
                    return;
                }
                pushDown();
                left.toString(builder);
                right.toString(builder);
            }

            public String toString() {
                StringBuilder builder = new StringBuilder();
                deepClone().toString(builder);
                if (builder.length() > 0) {
                    builder.setLength(builder.length() - 1);
                }
                return builder.toString();
            }

            private HeavyLightDecompose.Segment deepClone() {
                HeavyLightDecompose.Segment seg = clone();
                if (seg.left != null) {
                    seg.left = seg.left.deepClone();
                }
                if (seg.right != null) {
                    seg.right = seg.right.deepClone();
                }
                return seg;
            }

            protected HeavyLightDecompose.Segment clone() {
                try {
                    return (HeavyLightDecompose.Segment) super.clone();
                } catch (CloneNotSupportedException e) {
                    throw new RuntimeException(e);
                }
            }

        }

        public static class HLDNode {
            List<HeavyLightDecompose.HLDNode> next = new ArrayList<>(2);
            int id;
            int dfsOrderFrom;
            int dfsOrderTo;
            int size;
            HeavyLightDecompose.HLDNode link;
            HeavyLightDecompose.HLDNode heavy;
            HeavyLightDecompose.HLDNode father;

            public String toString() {
                return "" + id;
            }

        }

    }

    static class RandomWrapper {
        private Random random;
        public static final RandomWrapper INSTANCE = new RandomWrapper();

        public RandomWrapper() {
            this(new Random());
        }

        public RandomWrapper(Random random) {
            this.random = random;
        }

        public RandomWrapper(long seed) {
            this(new Random(seed));
        }

        public int nextInt(int l, int r) {
            return random.nextInt(r - l + 1) + l;
        }

    }

    static class Edge {
        int a;
        int b;
        int id;
        boolean visited;

    }
}