#include <bits/stdc++.h>
using namespace std;
const int inf = 1 << 28;
struct node {
  int c, max;
};
struct trnode {
  int fa, dep, tot, top, son, lc, rc;
  bool u;
  node c;
  trnode() { u = false; }
} tr[200010];
int tot = 0;
int ys[100010], la[100010], z = 0;
struct Node {
  int y, next;
} a[200010];
int len = 0, last[100010];
int n, q;
void ins(int x, int y) {
  a[++len].y = y;
  a[len].next = last[x];
  last[x] = len;
}
void pre_node(int x, int fa) {
  tr[x].fa = fa;
  tr[x].dep = tr[fa].dep + 1;
  tr[x].tot = 1;
  for (int i = last[x]; i; i = a[i].next) {
    int y = a[i].y;
    if (y == fa) continue;
    pre_node(y, x);
    tr[x].tot += tr[y].tot;
    if (tr[tr[x].son].tot < tr[y].tot) tr[x].son = y;
  }
}
void pre_edge(int x, int top) {
  tr[x].top = top;
  ys[x] = la[x] = ++z;
  if (tr[x].son) pre_edge(tr[x].son, top), la[x] = la[tr[x].son];
  for (int i = last[x]; i; i = a[i].next) {
    int y = a[i].y;
    if (y == tr[x].fa || y == tr[x].son) continue;
    pre_edge(y, y);
    la[x] = la[y];
  }
}
node update(node lc, node rc) {
  node ans;
  ans.c = lc.c + rc.c;
  ans.max = max(rc.max, lc.max + rc.c);
  return ans;
}
int bt(int l, int r) {
  int x = ++tot;
  if (l != r) {
    int mid = (l + r) / 2;
    tr[x].lc = bt(l, mid);
    tr[x].rc = bt(mid + 1, r);
    tr[x].c = update(tr[tr[x].lc].c, tr[tr[x].rc].c);
  } else
    tr[x].c.c = tr[x].c.max = -1;
  return x;
}
void pushdown(int x, int l, int r) {
  int lc = tr[x].lc, rc = tr[x].rc, mid = (l + r) / 2;
  tr[lc].c.c = -(mid - l + 1);
  tr[lc].c.max = -1;
  tr[lc].u = true;
  tr[rc].c.c = -(r - mid);
  tr[rc].c.max = -1;
  tr[rc].u = true;
  tr[x].u = false;
}
void change(int x, int l, int r, int fl, int fr, int c) {
  if (l == fl && r == fr) {
    if (c == inf)
      tr[x].c.c = -(r - l + 1), tr[x].c.max = -1, tr[x].u = true;
    else
      tr[x].c.c += c, tr[x].c.max += c;
    return;
  }
  if (tr[x].u) pushdown(x, l, r);
  int mid = (l + r) / 2;
  if (fr <= mid)
    change(tr[x].lc, l, mid, fl, fr, c);
  else if (fl > mid)
    change(tr[x].rc, mid + 1, r, fl, fr, c);
  else
    change(tr[x].lc, l, mid, fl, mid, c),
        change(tr[x].rc, mid + 1, r, mid + 1, fr, c);
  tr[x].c = update(tr[tr[x].lc].c, tr[tr[x].rc].c);
}
node findans(int x, int l, int r, int fl, int fr) {
  if (l == fl && r == fr) return tr[x].c;
  if (tr[x].u) pushdown(x, l, r);
  int mid = (l + r) / 2;
  if (fr <= mid) return findans(tr[x].lc, l, mid, fl, fr);
  if (fl > mid) return findans(tr[x].rc, mid + 1, r, fl, fr);
  return update(findans(tr[x].lc, l, mid, fl, mid),
                findans(tr[x].rc, mid + 1, r, mid + 1, fr));
}
int solve(int x) {
  node ans;
  ans.c = 0;
  ans.max = -inf;
  int tx = tr[x].top;
  while (tx) {
    ans = update(findans(1, 1, n, ys[tx], ys[x]), ans);
    x = tr[tx].fa;
    tx = tr[x].top;
  }
  return ans.max;
}
int main() {
  scanf("%d %d", &n, &q);
  bt(1, n);
  for (int i = 2; i <= n; i++) {
    int x;
    scanf("%d", &x);
    ins(x, i);
    ins(i, x);
  }
  pre_node(1, 0);
  pre_edge(1, 1);
  while (q--) {
    int op, x;
    scanf("%d %d", &op, &x);
    if (op == 1) change(1, 1, n, ys[x], ys[x], 1);
    if (op == 2) {
      change(1, 1, n, ys[x], la[x], inf);
      int k = solve(x);
      if (k > -1) change(1, 1, n, ys[x], ys[x], -(k + 1));
    }
    if (op == 3) {
      int k = solve(x);
      if (k > -1)
        printf("black\n");
      else
        printf("white\n");
    }
  }
}
