#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chkmin(T& a, T const& b) {
  return a > b ? a = b, true : false;
}
template <class T>
inline bool chkmax(T& a, T const& b) {
  return a < b ? a = b, true : false;
}
const int M = 100005;
const int N = M << 1;
struct BST {
  int bit[N];
  void insert(int i, int x) {
    while (i < N) bit[i] += x, i += i & -i;
  }
  int next(int i) {
    int sum = 0;
    while (i) sum += bit[i], i ^= i & -i;
    for (int k = 1 << 17; k; k >>= 1)
      if (i | k < N and sum >= bit[i | k]) sum -= bit[i |= k];
    return i + 1;
  }
} bst;
struct tree {
  int sum, mx;
  tree *ls, *rs;
  void update(int a, int b) {
    mx = max(b, a + mx);
    sum += a;
  }
  bool down() {
    if (sum == 0 and mx == -1) return false;
    ls = new tree(*ls);
    rs = new tree(*rs);
    ls->update(sum, mx);
    rs->update(sum, mx);
    sum = 0, mx = -1;
    return true;
  }
} * t[M], *null = new tree;
vector<int> E[M], O[M];
int op[M];
bool ans[M];
int n, m;
void update(int l, int r, tree*& p, int a, int b, int x, bool f = false) {
  if (!f) p = new tree(*p);
  if (l == a and r == b) return p->update(x, -1);
  int mid = l + r >> 1;
  f = p->down();
  if (a > mid)
    update(mid + 1, r, p->rs, a, b, x, f);
  else if (b <= mid)
    update(l, mid, p->ls, a, b, x, f);
  else
    update(l, mid, p->ls, a, mid, x, f),
        update(mid + 1, r, p->rs, mid + 1, b, x, f);
}
int query(int l, int r, tree*& p, int a, bool f = false) {
  if (!f) p = new tree(*p);
  if (l == r) return p->mx;
  int mid = l + r >> 1;
  f = p->down();
  if (a > mid)
    return query(mid + 1, r, p->rs, a, f);
  else
    return query(l, mid, p->ls, a, f);
}
void dfs(int u) {
  update(1, m, t[u], 1, m, -1);
  for (auto o : O[u]) {
    if (op[o] == 1) update(1, m, t[u], o, bst.next(o) - 1, 1);
    if (op[o] == 2) {
      int tmp = query(1, m, t[u], o) + 1;
      update(1, m, t[u], o, bst.next(o) - 1, -tmp);
      bst.insert(o, 1);
    }
    if (op[o] == 3) ans[o] = query(1, m, t[u], o) >= 0;
  }
  for (auto v : E[u]) t[v] = t[u], dfs(v);
  for (auto o : O[u])
    if (op[o] == 2) bst.insert(o, -1);
}
int main() {
  *null = (tree){0, -1, null, null};
  scanf("%d%d", &n, &m);
  for (int u = (2), u_end__ = (n + 1); u < u_end__; ++u) {
    int v;
    scanf("%d", &v);
    E[v].push_back(u);
  }
  for (int i = (1), i_end__ = (m + 1); i < i_end__; ++i) {
    int u;
    scanf("%d%d", op + i, &u);
    O[u].push_back(i);
  }
  bst.insert(m + 1, 1);
  t[1] = null, dfs(1);
  for (int i = (1), i_end__ = (m + 1); i < i_end__; ++i)
    if (op[i] == 3) puts(ans[i] ? "black" : "white");
  return 0;
}
