#include <bits/stdc++.h>   using namespace std;   void in(int &r) {     static char c;     r = 0;     while (c = getchar(), !isdigit(c))       ;     do r = (r << 1) + (r << 3) + (c ^ 48);     while (c = getchar(), isdigit(c));   }   const int mn = 100005;   int head[mn], ne[mn << 1], to[mn << 1], cnt1;   int fa[mn];   int n, m;   namespace part5 {   struct segment_tree {     bool mark[mn << 2];     int maxv[mn << 2], sum[mn << 2];     void up(int o) {       sum[o] = sum[o << 1] + sum[o << 1 | 1];       maxv[o] = max(maxv[o << 1] + sum[o << 1 | 1], maxv[o << 1 | 1]);     }     int L[mn << 2], R[mn << 2];     void build(int o, int l, int r) {       L[o] = l, R[o] = r;       if (l == r) {         sum[o] = -1;         maxv[o] = -1;         return;       }       int mid = l + r >> 1;       build(o << 1, l, mid);       build(o << 1 | 1, mid + 1, r);       up(o);     }     int y_1, y_2;     void down(int o) {       if (mark[o]) {         mark[o << 1] = 1;         sum[o << 1] = -(R[o << 1] - L[o << 1] + 1);         maxv[o << 1] = -1;         mark[o << 1 | 1] = 1;         sum[o << 1 | 1] = -(R[o << 1 | 1] - L[o << 1 | 1] + 1);         maxv[o << 1 | 1] = -1;         mark[o] = 0;       }     }     void mk(int o, int l, int r) {       if (y_1 <= l && r <= y_2) {         maxv[o] = -1, mark[o] = 1, sum[o] = -(r - l + 1);         return;       }       down(o);       int mid = l + r >> 1;       if (y_1 <= mid) mk(o << 1, l, mid);       if (y_2 > mid) mk(o << 1 | 1, mid + 1, r);       up(o);     }     void mk(int l, int r) {       y_1 = l, y_2 = r;       mk(1, 1, n);     }     int ad_v;     void add(int o, int l, int r) {       if (l == r) {         sum[o] += ad_v;         maxv[o] += ad_v;         return;       }       down(o);       int mid = l + r >> 1;       if (y_1 <= mid)         add(o << 1, l, mid);       else         add(o << 1 | 1, mid + 1, r);       up(o);     }     void add(int x, int v) {       y_1 = x, ad_v = v;       add(1, 1, n);     }     int S, Mx;     void ask(int o, int l, int r) {       if (y_1 <= l && r <= y_2) {         Mx = max(Mx, maxv[o] + S);         S += sum[o];         return;       }       down(o);       int mid = l + r >> 1;       if (y_2 > mid) ask(o << 1 | 1, mid + 1, r);       if (y_1 <= mid) ask(o << 1, l, mid);     }     pair<int, int> ask(int l, int r) {       y_1 = l, y_2 = r;       S = 0, Mx = -1;       ask(1, 1, n);       return make_pair(S, Mx);     }   } an;   int sz[mn], son[mn], fa[mn], H[mn], high;   void dfs(int x, int f) {     H[x] = ++high, sz[x] = 1, fa[x] = f;     for (int q(head[x]); q; q = ne[q])       if (to[q] != f) {         dfs(to[q], x);         sz[x] += sz[to[q]];         if (sz[to[q]] > sz[son[x]]) son[x] = to[q];       }     --high;   }   int dfn_l[mn], dfn_r[mn], ind, top[mn];   void redfs(int x, int f, int tp) {     dfn_l[x] = ++ind, top[x] = tp;     if (son[x]) redfs(son[x], x, tp);     for (int q(head[x]); q; q = ne[q])       if (to[q] != f && to[q] != son[x]) redfs(to[q], x, to[q]);     dfn_r[x] = ind;   }   pair<int, int> get(int x) {     int S = 0, Mx = -1;     while (x) {       pair<int, int> now = an.ask(dfn_l[top[x]], dfn_l[x]);       Mx = max(Mx, now.second + S);       S += now.first;       x = fa[top[x]];     }     return make_pair(S, Mx);   }   void solve() {     dfs(1, 0);     redfs(1, 0, 1);     an.build(1, 1, n);     int ty, x;     while (m--) {       in(ty), in(x);       if (ty == 1)         an.add(dfn_l[x], 1);       else if (ty == 2) {         an.mk(dfn_l[x], dfn_r[x]);         pair<int, int> now = get(x);         if (now.second != -1) an.add(dfn_l[x], -(1 + now.second));         now = get(x);       } else {         pair<int, int> now = get(x);         if (now.second != -1)           puts( black );         else           puts( white );       }     }   }   }  // namespace part5   int main() {     in(n), in(m);     int a;     for (int q = 2, q_end_ = n; q <= q_end_; ++q)       in(a), to[++cnt1] = a, ne[cnt1] = head[q], head[q] = cnt1, to[++cnt1] = q,              ne[cnt1] = head[a], head[a] = cnt1;     part5::solve();     return 0;   }