#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimization("unroll-loops")
using namespace std;
using ll = long long;
template <class T>
using V = vector<T>;
template <class T, class U>
using P = pair<T, U>;
using vll = V<ll>;
using vii = V<int>;
using vvll = V<vll>;
using vvii = V<V<int> >;
using PII = P<int, int>;
using PLL = P<ll, ll>;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class A, class B>
ostream &operator<<(ostream &out, const P<A, B> &p) {
  return out << '(' << p.first << ", " << p.second << ')';
}
template <class A>
ostream &operator<<(ostream &out, const V<A> &v) {
  out << '[';
  for (int i = 0; i < int(v.size()); i++) {
    if (i) out << ", ";
    out << v[i];
  }
  return out << ']';
}
const long long MOD = 1000000007;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;
template <typename T, typename C, int B = 30>
class BinaryTrie {
  struct Node {
    int cnt;
    Node *ch[2];
    Node() : cnt(0), ch{nullptr, nullptr} {}
  };
  virtual Node *clone(Node *t) { return t; }
  Node *add(Node *cr, T val, C cnt, int dep, bool need = true) {
    if (need) cr = clone(cr);
    cr->cnt += cnt;
    if (dep != -1) {
      int bit = val >> dep & 1;
      auto &chn = cr->ch[bit];
      if (chn == nullptr) chn = new Node(), need = false;
      chn = add(chn, val, cnt, dep - 1, need);
    }
    return cr;
  }
  T kth_element(Node *cr, C k, int dep, T xor_val) {
    if (dep == -1) return T(0);
    int bit = xor_val >> dep & 1;
    if (cr->ch[bit] == nullptr || cr->ch[bit]->cnt <= k) {
      T ret =
          kth_element(cr->ch[bit ^ 1],
                      k - (cr->ch[bit] == nullptr ? C(0) : cr->ch[bit]->cnt),
                      dep - 1, xor_val);
      ret |= T(1) << dep;
      return ret;
    } else {
      return kth_element(cr->ch[bit], k, dep - 1, xor_val);
    }
  }
  Node *find(Node *cr, T val, int dep, T xor_val) {
    if (dep == -1)
      return cr;
    else {
      int bit = xor_val >> dep & 1;
      bit ^= val >> dep & 1;
      if ((*cr).ch[bit])
        return find(cr->ch[bit], val, dep - 1, xor_val);
      else
        return nullptr;
    }
  }
  C count_less_xor(Node *cr, T val, int dep, T xor_val) {
    if (dep == -1) return C(0);
    C ret = 0;
    int bit = xor_val >> dep & 1;
    if (bit ^ (val >> dep & 1)) {
      if (cr->ch[bit] != nullptr) ret += cr->cnt;
      if (cr->ch[bit ^ 1] != nullptr)
        ret += count_less(cr->ch[bit ^ 1], val, dep - 1, xor_val);
    } else {
      if (cr->ch[bit] != nullptr)
        ret += count_less(cr->ch[bit], val, dep - 1, xor_val);
    }
    return ret;
  }
  C count_less(Node *cr, T val, int dep, T xor_val) {
    if (dep == -1) return C(0);
    C ret = 0;
    int bit = xor_val >> dep & 1;
    if (val >> dep & 1) {
      if (cr->ch[bit] != nullptr) ret += cr->ch[bit]->cnt;
      if (cr->ch[bit ^ 1] != nullptr)
        ret += count_less(cr->ch[bit ^ 1], val, dep - 1, xor_val);
    } else {
      if (cr->ch[bit] != nullptr)
        ret += count_less(cr->ch[bit], val, dep - 1, xor_val);
    }
    return ret;
  }

 public:
  Node *root;
  BinaryTrie() : root(new Node()) {}
  BinaryTrie(Node *root) : root(root) {}
  int size() const { return root ? root->cnt : 0; }
  bool empty() const { return !root; }
  void insert(const T &val, C cnt = C(1), T xor_val = T(0)) {
    add(root, val ^ xor_val, cnt, B);
  };
  void erase(const T &val, T xor_val = T(0)) {
    add(root, val ^ xor_val, -1, B);
  }
  T min_element(T xor_val = T(0)) {
    assert(root->cnt > 0);
    return kth_element(root, 0, B, xor_val);
  }
  T max_element(T xor_val = T(0)) {
    assert(root->cnt > 0);
    return kth_element(root, root->cnt - 1, B, xor_val);
  }
  T kth_element(C k, T xor_val = T(0)) {
    assert(k < root->cnt && k >= 0);
    return kth_element(root, k, B, xor_val);
  }
  C count(T val, T xor_val = T(0)) {
    Node *node = find(root, val, B, xor_val);
    return node == nullptr ? C(0) : node->cnt;
  }
  C count_less(T val, T xor_val = T(0)) {
    return count_less(root, val, B, xor_val);
  }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int q;
  cin >> q;
  BinaryTrie<int, int> bt;
  for (ll i = 0; i < q; i++) {
    int t;
    cin >> t;
    if (t == 1) {
      int p;
      cin >> p;
      bt.insert(p);
    } else if (t == 2) {
      int p;
      cin >> p;
      bt.erase(p);
    } else {
      int p, l;
      cin >> p >> l;
      cout << bt.count_less(l, p) << '\n';
    }
  }
  return 0;
}
