#include <bits/stdc++.h>
using namespace std;
int trie[30000005 / 2][2], cnt[30000005];
int sz = 0;
string f(int num) {
  string s = "";
  while (num != 0) {
    int mod = num % 2;
    s += (char)(mod + (int)'0');
    num = num / 2;
  }
  reverse(s.begin(), s.end());
  while (s.length() < 30) s = "0" + s;
  return s;
}
void add(int num) {
  string s = f(num);
  int curNode = 0;
  cnt[curNode]++;
  for (int i = 0; i < s.length(); i++) {
    int p = s[i] - '0';
    if (trie[curNode][p] == -1) {
      trie[curNode][p] = ++sz;
    }
    curNode = trie[curNode][p];
    cnt[curNode]++;
  }
}
void dlt(int num) {
  string s = f(num);
  int curNode = 0;
  cnt[curNode]--;
  for (int i = 0; i < s.length(); i++) {
    int p = s[i] - '0';
    curNode = trie[curNode][p];
    cnt[curNode]--;
  }
}
int query(int p, int l) {
  string t = f(p);
  string has = f(l);
  int ans = 0;
  int curNode = 0;
  for (int i = 0; i < t.size(); i++) {
    int p = t[i] - '0';
    int q = has[i] - '0';
    int x = p ^ q;
    if (trie[curNode][x] == -1) {
      trie[curNode][x] = ++sz;
    }
    if (trie[curNode][0] == -1) {
      trie[curNode][0] = ++sz;
    }
    if (trie[curNode][1] == -1) {
      trie[curNode][1] = ++sz;
    }
    int altNode0 = trie[curNode][0];
    int altNode1 = trie[curNode][1];
    curNode = trie[curNode][x];
    if (q == 1) {
      if (p == 1)
        ans += cnt[altNode1];
      else
        ans += cnt[altNode0];
    }
  }
  return ans;
}
int main() {
  memset(trie, -1, sizeof trie);
  memset(cnt, 0, sizeof cnt);
  int q;
  scanf("%d", &q);
  for (int i = 1; i <= q; i++) {
    int type, p, l;
    scanf("%d %d", &type, &p);
    if (type == 1) {
      add(p);
    } else if (type == 2) {
      dlt(p);
    } else {
      scanf("%d", &l);
      int ans = query(p, l);
      printf("%d\n", ans);
    }
  }
}
