#include <bits/stdc++.h>
#define REP(i, a, n) for(ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;

template<typename T, typename E> class LazySegmentTree {
public:
  typedef function<T (T, T)> Operator;
  typedef function<E (E, E)> Merge;
  typedef function<T (T, E)> Apply;
  typedef function<E (E, ll)> Product;

  vector<T> data;
  vector<E> lazy;
  ll n;        // size of elements (2^x alignment)
  T e;         // identity of monoid
  Operator op; // binary operator of monoid
  E d;         // identity of effect
  Merge merge; // merge effects
  Apply apply; // apply effect to monoid
  Product p;   // calculate effect * n

  // construction with size of elements
  LazySegmentTree(ll _n, T e, Operator op, E d, Merge merge, Apply apply, Product p):
    e(e), op(op), d(d), merge(merge), apply(apply), p(p) {
    for(n = 1; n < _n; n *= 2);
    data.resize(n * 2 - 1, e);
    lazy.resize(n * 2 - 1, d);
  }

  // construction with initial values
  LazySegmentTree(const vector<T> &vec, T e, Operator op, E d, Merge merge, Apply apply, Product p):
    e(e), op(op), d(d), merge(merge), apply(apply), p(p) {
    for(n = 1; n < (ll) vec.size(); n *= 2);
    data.resize(n * 2 - 1, e);
    lazy.resize(n * 2 - 1, d);
    REP(i, 0, vec.size()) data[i + n - 1] = vec[i];
    for(ll i = n - 2; i >= 0; i--) data[i] = op(data[i * 2 + 1], data[i * 2 + 2]);
  }

  // evaluate lazy update
  void eval(ll k, ll l, ll r) {
    if(r - l > 1) {
      lazy[k * 2 + 1] = merge(lazy[k * 2 + 1], lazy[k]);
      lazy[k * 2 + 2] = merge(lazy[k * 2 + 2], lazy[k]);
    }
    data[k] = apply(data[k], p(lazy[k], r - l));
    lazy[k] = d;
  }

  // query for [a, b)
  T query(ll a, ll b) { return query(a, b, 0, 0, n); }
  T query(ll a, ll b, ll k, ll l, ll r) {
    eval(k, l, r);
    if(r <= a || b <= l) return e;
    if(a <= l && r <= b) return data[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return op(vl, vr);
  }

  // update values of [a, b)
  T update(ll a, ll b, E x) { return update(a, b, x, 0, 0, n); }
  T update(ll a, ll b, E x, ll k, ll l, ll r) {
    eval(k, l, r);
    if(r <= a || b <= l) return data[k];
    if(a <= l && r <= b) {
      lazy[k] = merge(lazy[k], x);
      return apply(data[k], p(lazy[k], r - l));
    }
    T vl = update(a, b, x, k * 2 + 1, l, (l + r) / 2);
    T vr = update(a, b, x, k * 2 + 2, (l + r) / 2, r);
    return data[k] = op(vl, vr);
  }
};

void dfs(ll v, const vector< vector<ll> > &E, vector<ll> &s, vector<ll> &t, ll &d) {
  s[v] = d++;
  for(ll u : E[v]) dfs(u, E, s, t, d);
  t[v] = d;
}

int main(void) {
  ll N, Q;
  cin >> N >> Q;
  vector< vector<ll> > E(N);
  REP(i, 1, N) {
    ll P;
    cin >> P;
    P--;
    E[P].push_back(i);
  }
  vector<char> C(N);
  REP(i, 0, N) cin >> C[i];
  vector<ll> V(Q);
  REP(i, 0, Q) {
    cin >> V[i];
    V[i]--;
  }

  ll d = 0;
  vector<ll> s(N), t(N);
  dfs(0, E, s, t, d);

  vector<pll> A(N);
  REP(i, 0, N) {
    if(C[i] == 'G') A[s[i]] = pll(1, 0);
    if(C[i] == 'W') A[s[i]] = pll(0, 1);
  }

  LazySegmentTree<pll, ll>::Operator op = [](pll a, pll b) { return pll(a.first + b.first, a.second + b.second); };
  LazySegmentTree<pll, ll>::Merge merge = [](ll x, ll y) { return (x + y) % 2; };
  LazySegmentTree<pll, ll>::Apply apply = [](pll a, ll x) { return x % 2 == 0 ? a : pll(a.second, a.first); };
  LazySegmentTree<pll, ll>::Product p = [](ll x, ll n) { return x; };
  LazySegmentTree<pll, ll> segtree(A, pll(0, 0), op, 0, merge, apply, p);

  REP(i, 0, Q) {
    ll v = V[i];
    segtree.update(s[v], t[v], 1);
    pll cnt = segtree.query(0, N);
    if(cnt.first > cnt.second) cout << "broccoli" << endl;
    if(cnt.first < cnt.second) cout << "cauliflower" << endl;
  }
}



Measured memory_bytes: 26340