#include <bits/stdc++.h>
#pragma G++ optimize "O2"
#pragma GCC optimize "O2"
#pragma G++ optimize "O3"
#pragma GCC optimize "O3"
#pragma G++ optimize "Ofast"
#pragma GCC optimize "Ofast"
using namespace std;
const int maxh = 30;
struct Trie {
  int son[3300000][2];
  int cnt[3300000];
  int totid;
  Trie() { totid = 0; }
  void insert(int val) {
    int p = 0;
    for (register int i = maxh; i >= 0; i--) {
      int nowbit = (val >> i) & 1;
      if (son[p][nowbit]) {
        p = son[p][nowbit];
        cnt[p]++;
      } else {
        p = son[p][nowbit] = ++totid;
        cnt[p]++;
      }
    }
  }
  void del(int val) {
    int p = 0;
    for (register int i = maxh; i >= 0; i--) {
      int nowbit = (val >> i) & 1;
      if (son[p][nowbit]) {
        p = son[p][nowbit];
        cnt[p]--;
      } else
        return;
    }
  }
  int query(int pi, int li) {
    long long now = 0, ret = 0;
    for (register int i = maxh; i >= 0; i--) {
      int libit = (li >> i) & 1;
      int pibit = (pi >> i) & 1;
      if (libit) {
        if (pibit) {
          if (son[now][1]) ret += cnt[son[now][1]];
          now = son[now][0];
        } else {
          if (son[now][0]) ret += cnt[son[now][0]];
          now = son[now][1];
        }
      } else {
        if (pibit) {
          now = son[now][1];
        } else {
          now = son[now][0];
        }
      }
      if (!now) break;
    }
    return ret;
  }
} trie;
int Q;
int main() {
  scanf("%d", &Q);
  while (Q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int pp;
      scanf("%d", &pp);
      trie.insert(pp);
    } else if (op == 2) {
      int pp;
      scanf("%d", &pp);
      trie.del(pp);
    } else {
      int pi, li;
      scanf("%d%d", &pi, &li);
      printf("%d\n", trie.query(pi, li));
    }
  }
  return 0;
}
