#include <bits/stdc++.h>   using namespace std;   template <class T>   inline void read(T &x) {     x = 0;     char c = getchar();     int f = 1;     while (!isdigit(c)) {       if (c ==  - ) f = -1;       c = getchar();     }     while (isdigit(c)) {       x = x * 10 + c -  0 ;       c = getchar();     }     x *= f;   }   template <class T>   T gcd(T a, T b) {     return !b ? a : gcd(b, a % b);   }   template <class T>   inline void cmin(T &x, T y) {     x = x < y ? x : y;   }   template <class T>   inline void cmax(T &x, T y) {     x = x > y ? x : y;   }   const int N = 100010;   int n, q, head[N], nxt[N], v[N], cnt, son[N], top[N], si[N], wp[N], totw, id[N],       fa[N];   inline void add(int x, int y) {     nxt[++cnt] = head[x];     head[x] = cnt;     v[cnt] = y;   }   struct seg {     int l, r, sum, sufma, al;   } t[N << 2];   void dfs(int now) {     int mx = -1;     si[now] = 1;     for (register int i = head[now]; i; i = nxt[i]) {       dfs(v[i]);       si[now] += si[v[i]];       if (si[v[i]] > mx) son[now] = v[i];     }   }   void _dfs(int now, int tf) {     top[now] = tf;     wp[now] = ++totw;     id[totw] = now;     if (!son[now]) return;     _dfs(son[now], tf);     for (register int i = head[now]; i; i = nxt[i]) {       if (son[now] != v[i]) _dfs(v[i], v[i]);     }   }   void merge(seg &a, seg b, seg c) {     a.sum = b.sum + c.sum;     a.sufma = max(c.sufma, c.sum + b.sufma);   }   void build(int p, int l, int r) {     t[p].l = l;     t[p].r = r;     if (l == r) {       t[p].sum = t[p].sufma = -1;       return;     }     int mid = (l + r) >> 1;     build(p << 1, l, mid);     build(p << 1 | 1, mid + 1, r);     merge(t[p], t[p << 1], t[p << 1 | 1]);   }   void pushdown(int p) {     if (t[p].al != 0) {       t[p << 1].al = t[p << 1 | 1].al = t[p].al;       t[p << 1].sum = (t[p << 1].r - t[p << 1].l + 1) * t[p << 1].al;       t[p << 1 | 1].sum =           (t[p << 1 | 1].r - t[p << 1 | 1].l + 1) * t[p << 1 | 1].al;       t[p << 1].sufma = t[p << 1 | 1].sufma = -1;       t[p].al = 0;     }   }   void change(int p, int x, int dt) {     if (t[p].l == t[p].r) {       t[p].sufma += dt;       t[p].sum += dt;       return;     }     pushdown(p);     int mid = (t[p].l + t[p].r) >> 1;     if (x <= mid)       change(p << 1, x, dt);     else       change(p << 1 | 1, x, dt);     merge(t[p], t[p << 1], t[p << 1 | 1]);   }   void modify(int p, int l, int r, int dt) {     if (t[p].l >= l && t[p].r <= r) {       t[p].al = dt;       t[p].sum = (t[p].r - t[p].l + 1) * t[p].al;       t[p].sufma = -1;       return;     }     pushdown(p);     int mid = (t[p].l + t[p].r) >> 1;     if (l <= mid) modify(p << 1, l, r, dt);     if (r > mid) modify(p << 1 | 1, l, r, dt);     merge(t[p], t[p << 1], t[p << 1 | 1]);   }   seg maxsuf(int p, int l, int r) {     if (t[p].l >= l && t[p].r <= r) {       return t[p];     }     pushdown(p);     int mid = (t[p].l + t[p].r) >> 1;     if (r <= mid) return maxsuf(p << 1, l, r);     if (l > mid) return maxsuf(p << 1 | 1, l, r);     seg tmp;     merge(tmp, maxsuf(p << 1, l, r), maxsuf(p << 1 | 1, l, r));     return tmp;   }   int query(int x) {     seg res = maxsuf(1, wp[top[x]], wp[x]);     x = fa[top[x]];     while (x) {       merge(res, maxsuf(1, wp[top[x]], wp[x]), res);       x = fa[top[x]];     }     return res.sufma;   }   int main() {     read(n);     read(q);     for (register int i = (2); i <= (n); i++) {       read(fa[i]);       add(fa[i], i);     }     dfs(1);     _dfs(1, 1);     build(1, 1, n);     for (register int i = (1); i <= (q); i++) {       int opt, x;       read(opt);       read(x);       if (opt == 1) {         change(1, wp[x], 1);       } else if (opt == 2) {         modify(1, wp[x], wp[x] + si[x] - 1, -1);         change(1, wp[x], -(query(x) + 1));       } else {         if (query(x) >= 0) {           printf( black n );         } else {           printf( white n );         }       }     }     return 0;   }