#include <bits/stdc++.h>
using namespace std;
struct node1 {
  long long x, y, next;
} a[200010];
struct node2 {
  long long l, r, lc, rc, n, lazy, sum, ma;
} tr[200010];
long long last[100010], size[100010], son[100010], dep[100010], fa[100010],
    tp[100010], id[100010];
long long n, q, len = 0;
void ins(long long x, long long y) {
  a[++len] = (node1){x, y, last[x]};
  last[x] = len;
}
void dfs1(long long x) {
  size[x] = 1;
  for (long long i = last[x]; i; i = a[i].next) {
    long long y = a[i].y;
    if (y == fa[x]) continue;
    fa[y] = x;
    dep[y] = dep[x] + 1;
    dfs1(y);
    size[x] += size[y];
    if (size[y] > size[son[x]]) son[x] = y;
  }
}
long long cnt = 0;
void dfs2(long long x, long long top) {
  tp[x] = top;
  id[x] = ++cnt;
  if (son[x]) dfs2(son[x], top);
  for (long long i = last[x]; i; i = a[i].next) {
    long long y = a[i].y;
    if (y == son[x] || y == fa[x]) continue;
    dfs2(y, y);
  }
}
long long Len = 0;
void pushup(long long now) {
  long long lc = tr[now].lc, rc = tr[now].rc;
  tr[now].sum = tr[lc].sum + tr[rc].sum;
  tr[now].ma = max(tr[lc].ma + tr[rc].sum, tr[rc].ma);
}
void build(long long l, long long r) {
  long long now = ++Len;
  tr[now] = (node2){l, r, -1, -1, r - l + 1, 0, 0, 0};
  if (l == r) {
    tr[now].sum = tr[now].ma = -1;
    return;
  }
  long long mid = (l + r) >> 1;
  tr[now].lc = Len + 1, build(l, mid);
  tr[now].rc = Len + 1, build(mid + 1, r);
  pushup(now);
}
void update(long long now) {
  if (!tr[now].lazy) return;
  long long lc = tr[now].lc, rc = tr[now].rc;
  if (lc != -1) tr[lc].lazy = 1, tr[lc].sum = -tr[lc].n, tr[lc].ma = -1;
  if (rc != -1) tr[rc].lazy = 1, tr[rc].sum = -tr[rc].n, tr[rc].ma = -1;
  tr[now].lazy = 0;
}
void add(long long now, long long x, long long d) {
  update(now);
  if (tr[now].l == tr[now].r) {
    tr[now].sum += d;
    tr[now].ma += d;
    return;
  }
  long long lc = tr[now].lc, rc = tr[now].rc,
            mid = (tr[now].l + tr[now].r) >> 1;
  if (x <= mid)
    add(lc, x, d);
  else
    add(rc, x, d);
  pushup(now);
}
void change(long long now, long long l, long long r) {
  update(now);
  if (tr[now].l == l && tr[now].r == r) {
    tr[now].sum = -tr[now].n;
    tr[now].ma = -1;
    tr[now].lazy = 1;
    return;
  }
  long long lc = tr[now].lc, rc = tr[now].rc,
            mid = (tr[now].l + tr[now].r) >> 1;
  if (r <= mid)
    change(lc, l, r);
  else if (l > mid)
    change(rc, l, r);
  else
    change(lc, l, mid), change(rc, mid + 1, r);
  pushup(now);
}
node2 findmax(long long now, long long l, long long r) {
  update(now);
  if (tr[now].l == l && tr[now].r == r) return tr[now];
  long long lc = tr[now].lc, rc = tr[now].rc,
            mid = (tr[now].l + tr[now].r) >> 1;
  if (r <= mid)
    return findmax(lc, l, r);
  else if (l > mid)
    return findmax(rc, l, r);
  else {
    node2 t1 = findmax(lc, l, mid), t2 = findmax(rc, mid + 1, r),
          t = (node2){0, 0, 0, 0, 0, 0, 0, 0};
    t.sum = t1.sum + t2.sum;
    t.ma = max(t1.ma + t2.sum, t2.ma);
    return t;
  }
}
long long solve(long long x) {
  long long sum = 0, ans = -(long long)1e9;
  while (x) {
    node2 NOW = findmax(1, id[tp[x]], id[x]);
    ans = max(ans, sum + NOW.ma);
    sum += NOW.sum;
    x = fa[tp[x]];
  }
  return ans;
}
signed main() {
  long long t, x;
  scanf("%lld %lld", &n, &q);
  for (long long i = 2; i <= n; i++) {
    scanf("%lld", &x);
    ins(i, x), ins(x, i);
  }
  dfs1(1);
  dfs2(1, 1);
  build(1, n);
  for (long long i = 1; i <= q; i++) {
    scanf("%lld %lld", &t, &x);
    if (t == 1)
      add(1, id[x], 1);
    else if (t == 2)
      change(1, id[x], id[x] + size[x] - 1), add(1, id[x], -(solve(x) + 1));
    else if (t == 3)
      printf(solve(x) >= 0 ? "black\n" : "white\n");
  }
}
