#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
constexpr int MOD = 1000000007;
constexpr ll INF = (1LL << 61) - 1;
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T>
void fail(T v) {
  cout << v << endl;
  exit(0);
}
struct Node {
  int val;
  Node *par;
  int idx;
  Node *lft;
  Node *rgt;
  Node(int v, Node *p, int i = -1)
      : val(v), par(p), idx(i), lft(NULL), rgt(NULL) {}
};
int sz;
Node *root;
Node *InsertNode(Node *leaf, int l, int r, int idx, bool isLeft) {
  Node *rt = new Node(0, NULL, idx);
  while (true) {
    Node *v = new Node(0, leaf->par);
    if (isLeft)
      leaf->par->lft = v;
    else
      leaf->par->rgt = v;
    leaf->par = v;
    bool a = leaf->idx < ((l + r) >> 1), b = idx < ((l + r) >> 1);
    if (a) {
      isLeft = true;
      v->lft = leaf;
      r = (l + r) >> 1;
      if (!b) {
        v->rgt = rt;
        break;
      }
    } else {
      isLeft = false;
      v->rgt = leaf;
      l = (l + r) >> 1;
      if (b) {
        v->lft = rt;
        break;
      }
    }
  }
  rt->par = leaf->par;
  return rt;
}
void Update(int i, bool cl = false) {
  Node *now = root;
  int l = 0, r = sz;
  while (r - l > 1) {
    if (now->idx != -1) break;
    if (i < ((l + r) >> 1)) {
      if (now->lft == NULL) {
        now->lft = new Node(0, now, i);
        now = now->lft;
        break;
      }
      if (now->lft->idx != -1 && now->lft->idx != i) {
        now = InsertNode(now->lft, l, (r + l) >> 1, i, true);
        break;
      }
      now = now->lft;
      r = (l + r) >> 1;
    } else {
      if (now->rgt == NULL) {
        now->rgt = new Node(0, now, i);
        now = now->rgt;
        break;
      }
      if (now->rgt->idx != -1 && now->rgt->idx != i) {
        now = InsertNode(now->rgt, (l + r) >> 1, r, i, false);
        break;
      }
      now = now->rgt;
      l = (l + r) >> 1;
    }
  }
  if (cl)
    now->val--;
  else
    now->val++;
  while (now->par != NULL) {
    auto p = now->par;
    int v = 0;
    if (p->lft != NULL) v += p->lft->val;
    if (p->rgt != NULL) v += p->rgt->val;
    p->val = v;
    now = p;
  }
}
int Query(Node *now, int a, int b, int P, int L) {
  if (~(now->idx)) {
    if ((P ^ now->idx) < L) return now->val;
    return 0;
  }
  if (!now || b <= a) return 0;
  int s = (b - a) >> 1;
  if (L & s) {
    if (P & s) {
      int add = 0;
      if (now->rgt != NULL) add += now->rgt->val;
      if (now->lft != NULL)
        return add + Query(now->lft, a, (a + b) >> 1, P, L);
      else
        return add;
    } else {
      int add = 0;
      if (now->lft != NULL) add += now->lft->val;
      if (now->rgt != NULL)
        return add + Query(now->rgt, (a + b) >> 1, b, P, L);
      else
        return add;
    }
  } else {
    if (P & s) {
      if (now->rgt != NULL) return Query(now->rgt, (a + b) >> 1, b, P, L);
      return 0;
    } else {
      if (now->lft != NULL) return Query(now->lft, a, (a + b) >> 1, P, L);
      return 0;
    }
  }
}
void solve() {
  int Q;
  scanf("%d", &Q);
  sz = 1;
  while (sz < (int)1e8 + 1) sz <<= 1;
  int now = 0;
  root = new Node(0, NULL);
  while (Q--) {
    int t;
    scanf("%d", &t);
    if (t == 1) {
      now++;
      int p;
      scanf("%d", &p);
      Update(p);
    } else if (t == 2) {
      now--;
      int p;
      scanf("%d", &p);
      Update(p, 1);
    } else {
      int p, l;
      scanf("%d %d", &p, &l);
      printf("%d\n", Query(root, 0, sz, p, l));
    }
  }
}
int main() {
  solve();
  return 0;
}
