#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
int N;
int mx(int x, int y) {
  if (x == y && x == MAXN) return MAXN;
  if (x == MAXN) return y;
  if (y == MAXN) return x;
  return max(x, y);
}
int mn(int x, int y) {
  if (x == y && x == MAXN) return MAXN;
  if (x == MAXN) return y;
  if (y == MAXN) return x;
  return min(x, y);
}
struct Tree {
  int par[MAXN], childMx[MAXN], childMn[MAXN];
  int Eu[MAXN], st[MAXN], ed[MAXN];
  int parId[MAXN];
  int at(int x) { return x; }
  set<int> dx[MAXN];
  struct OpposeIT {
    struct node {
      int mxPar, mnPar, mnChild, mxChild;
      void merge(node a, node b, Tree &tr) {
        if (b.mxPar == 0) return *this = a, void();
        if (a.mxPar == 0) return *this = b, void();
        mxPar =
            (mx(tr.par[a.mxPar], tr.par[b.mxPar]) == tr.par[a.mxPar] ? a.mxPar
                                                                     : b.mxPar);
        mnPar =
            (mn(tr.par[a.mnPar], tr.par[b.mnPar]) == tr.par[a.mnPar] ? a.mnPar
                                                                     : b.mnPar);
        mxChild =
            (mx(tr.childMx[tr.at(a.mxChild)], tr.childMx[tr.at(b.mxChild)]) ==
                     tr.childMx[tr.at(a.mxChild)]
                 ? a.mxChild
                 : b.mxChild);
        mnChild =
            (mn(tr.childMn[tr.at(a.mnChild)], tr.childMn[tr.at(b.mnChild)]) ==
                     tr.childMn[tr.at(a.mnChild)]
                 ? a.mnChild
                 : b.mnChild);
      }
    } T[4 * MAXN];
    void init(int v, int l, int r, Tree &tr, Tree &th) {
      if (l == r) {
        T[v].mxPar = T[v].mnPar = T[v].mxChild = T[v].mnChild = th.Eu[l];
        return;
      }
      init(2 * v, l, ((l + r) >> 1), tr, th);
      init(2 * v + 1, ((l + r) >> 1) + 1, r, tr, th);
      T[v].merge(T[2 * v], T[2 * v + 1], tr);
    }
    void update(int v, int l, int r, int pos, Tree &tr) {
      if (l > pos || r < pos) return;
      if (l == r) return;
      update(2 * v, l, ((l + r) >> 1), pos, tr);
      update(2 * v + 1, ((l + r) >> 1) + 1, r, pos, tr);
      T[v].merge(T[2 * v], T[2 * v + 1], tr);
    }
    node get(int v, int l, int r, int i, int j, Tree &tr) {
      if (l > j || r < i) return node();
      if (i <= l && r <= j) return T[v];
      node ans;
      ans.merge(get(2 * v, l, ((l + r) >> 1), i, j, tr),
                get(2 * v + 1, ((l + r) >> 1) + 1, r, i, j, tr), tr);
      return ans;
    }
  } Op;
  vector<int> G[MAXN];
  int dfs(int v, int Time = 0) {
    Eu[++Time] = v;
    st[v] = Time;
    for (auto u : G[v]) {
      if (st[u]) continue;
      parId[u] = v;
      Time = dfs(u, Time);
    }
    ed[v] = Time;
    return Time;
  }
  void prep() {
    par[1] = MAXN, parId[1] = MAXN;
    dfs(1);
  }
  void rem(int u, int v, int eupos) {
    if (st[u] > st[v]) swap(u, v);
    par[v] = MAXN;
    dx[u].erase(eupos);
    childMx[u] = (dx[u].size() ? *(--dx[u].end()) : MAXN);
    childMn[u] = (dx[u].size() ? *(dx[u].begin()) : MAXN);
  }
} Tr[2];
void prep() {
  Tr[0].prep();
  Tr[1].prep();
  for (int i = 0; i < 2; ++i) {
    for (int j = 2; j <= N; ++j) {
      Tr[i].par[j] = Tr[!i].st[Tr[i].parId[j]];
      Tr[i].dx[Tr[i].parId[j]].insert(Tr[!i].st[j]);
    }
    for (int u = 1; u <= N; ++u) {
      Tr[i].childMx[u] = (Tr[i].dx[u].size() ? *(--Tr[i].dx[u].end()) : MAXN);
      Tr[i].childMn[u] = (Tr[i].dx[u].size() ? *(Tr[i].dx[u].begin()) : MAXN);
    }
  }
  Tr[0].Op.init(1, 1, N, Tr[1], Tr[0]);
  Tr[1].Op.init(1, 1, N, Tr[0], Tr[1]);
}
vector<int> toRemove;
vector<int> toScan;
int input[2][MAXN];
void rem(int id, int u, int v) {
  if (Tr[id].st[u] > Tr[id].st[v]) swap(u, v);
  if (input[id][v] == u)
    toRemove.push_back(v - 1);
  else
    toRemove.push_back(u - 1);
  Tr[id].rem(u, v, Tr[!id].st[v]);
  Tr[!id].Op.update(1, 1, N, Tr[!id].st[v], Tr[id]);
  Tr[!id].Op.update(1, 1, N, Tr[!id].st[u], Tr[id]);
}
void scan(int id, int v) {
  do {
    auto X = Tr[id].Op.get(1, 1, N, Tr[id].st[v], Tr[id].ed[v], Tr[!id]);
    if (Tr[!id].par[X.mxPar] != MAXN && Tr[!id].par[X.mxPar] > Tr[id].ed[v]) {
      rem(!id, Tr[!id].parId[X.mxPar], X.mxPar);
      continue;
    }
    if (Tr[!id].par[X.mnPar] != MAXN && Tr[!id].par[X.mnPar] < Tr[id].st[v]) {
      rem(!id, Tr[!id].parId[X.mnPar], X.mnPar);
      continue;
    }
    if (Tr[!id].childMn[X.mnChild] != MAXN &&
        Tr[!id].childMn[X.mnChild] < Tr[id].st[v]) {
      rem(!id, Tr[id].Eu[Tr[!id].childMn[X.mnChild]], X.mnChild);
      continue;
    }
    if (Tr[!id].childMx[X.mxChild] != MAXN &&
        Tr[!id].childMx[X.mxChild] > Tr[id].ed[v]) {
      rem(!id, Tr[id].Eu[Tr[!id].childMx[X.mxChild]], X.mxChild);
      continue;
    }
    break;
  } while (true);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> N;
  for (int i = 0; i < 2; ++i) {
    for (int j = 2; j <= N; ++j) {
      int x;
      cin >> x;
      input[i][j] = x;
      Tr[i].G[x].push_back(j);
      Tr[i].G[j].push_back(x);
    }
  }
  prep();
  int K;
  cin >> K;
  rem(0, Tr[0].parId[K + 1], K + 1);
  printf("Blue\n%d\n", K);
  for (int s = 0;; ++s) {
    toScan = toRemove;
    toRemove.clear();
    for (auto u : toScan) scan((s & 1), u + 1);
    if (toRemove.empty()) break;
    printf("%s\n", ((s & 1) ? "Blue" : "Red"));
    sort(toRemove.begin(), toRemove.end());
    for (auto u : toRemove) printf("%d ", u);
    printf("\n");
  }
}
