As you might remember from the previous round, Vova is currently playing a strategic game known as Rage of Empires.

Vova managed to build a large army, but forgot about the main person in the army - the commander. So he tries to hire a commander, and he wants to choose the person who will be respected by warriors.

Each warrior is represented by his personality — an integer number pi. Each commander has two characteristics — his personality pj and leadership lj (both are integer numbers). Warrior i respects commander j only if <image> (<image> is the bitwise excluding OR of x and y).

Initially Vova's army is empty. There are three different types of events that can happen with the army:

  * 1 pi — one warrior with personality pi joins Vova's army; 
  * 2 pi — one warrior with personality pi leaves Vova's army; 
  * 3 pi li — Vova tries to hire a commander with personality pi and leadership li. 



For each event of the third type Vova wants to know how many warriors (counting only those who joined the army and haven't left yet) respect the commander he tries to hire.

Input

The first line contains one integer q (1 ≤ q ≤ 100000) — the number of events.

Then q lines follow. Each line describes the event:

  * 1 pi (1 ≤ pi ≤ 108) — one warrior with personality pi joins Vova's army; 
  * 2 pi (1 ≤ pi ≤ 108) — one warrior with personality pi leaves Vova's army (it is guaranteed that there is at least one such warrior in Vova's army by this moment); 
  * 3 pi li (1 ≤ pi, li ≤ 108) — Vova tries to hire a commander with personality pi and leadership li. There is at least one event of this type. 

Output

For each event of the third type print one integer — the number of warriors who respect the commander Vova tries to hire in the event.

Example

Input

5
1 3
1 4
3 6 3
2 4
3 6 3


Output

1
0

Note

In the example the army consists of two warriors with personalities 3 and 4 after first two events. Then Vova tries to hire a commander with personality 6 and leadership 3, and only one warrior respects him (<image>, and 2 < 3, but <image>, and 5 ≥ 3). Then warrior with personality 4 leaves, and when Vova tries to hire that commander again, there are no warriors who respect him.
import java.io.*;
import java.util.*;

public class Main {

    class IOManager {
        BufferedReader reader;
        PrintWriter writer;
        StringTokenizer tokenizer;

        IOManager() {
            reader = new BufferedReader(new InputStreamReader(System.in));
            writer = new PrintWriter(new BufferedOutputStream(System.out));
        }

        IOManager(String file) throws FileNotFoundException {
            reader = new BufferedReader(new FileReader(file));
            writer = new PrintWriter(new BufferedOutputStream(System.out));
        }

        String next() throws IOException {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                String line = reader.readLine();
                if (line == null)
                    throw new IOException("No lines left.");
                tokenizer = new StringTokenizer(line);
            }
            return tokenizer.nextToken();
        }

        public Integer nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public Long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public Double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public void writeSpace(Object obj) {
            writer.print(obj.toString() + " ");
        }

        public void writeLine(Object obj) {
            writer.println(obj.toString());
        }

        public void writeDouble(Double x, int n) {
            String format = "%." + n + "f";
            writer.printf(format, x);
        }

        public void write(Object obj) {
            writer.print(obj.toString());
        }

        public void close() {
            writer.close();
        }
    }

    class Pair implements Comparable {
        public long u, v;

        public Pair(long u, long v) {
            this.u = u;
            this.v = v;
        }

        @Override
        public int compareTo(Object o) {
            Pair that = (Pair) o;
            if (Long.compare(u, that.u) != 0)
                return Long.compare(u, that.u);
            return Long.compare(v, that.v);
        }
    }

    class Graph {
        public int n, m;
        public List<Integer>[] adj;

        public Graph(int n, int m) {
            this.n = n;
            this.m = m;
            adj = new List[n + 1];
            for (int i = 0; i <= n; ++i) {
                adj[i] = new ArrayList<>();
            }
        }

        public void add(int u, int v) {
            adj[u].add(v);
        }

        public void add2Ways(int u, int v) {
            add(u, v);
            add(v, u);
        }

        public void dfs(int i, boolean fr[]) {
            fr[i] = false;
            for (int j: adj[i]) {
                if (fr[j]) {
                    dfs(j, fr);
                }
            }
        }

        public boolean isConnected() {
            boolean fr[] = new boolean[n + 1];
            Arrays.fill(fr, true);
            dfs(1, fr);
            for (int i = 2; i <= n; ++i) {
                if (fr[i])
                    return false;
            }
            return true;
        }

        public boolean hasEuclideanPath() {
            if (!isConnected())
                return false;
            int cnt = 0;
            for (int i = 1; i <= n; ++i) {
                if (adj[i].size() % 2 == 1)
                    cnt++;
            }
            return cnt <= 2;
        }

        public boolean dfsHamiltonian(int i, boolean[] fr, int reached) {
            fr[i] = false;
            reached++;
            if (reached == n)
                return true;
            for (int j: adj[i]) {
                if (fr[j]) {
                    if (dfsHamiltonian(j, fr, reached))
                        return true;
                }
            }
            fr[i] = true;
            return false;
        }

        public boolean hasHamiltonianPathFrom(int st) {
            boolean fr[] = new boolean[n + 1];
            Arrays.fill(fr, true);
            return dfsHamiltonian(st, fr, 0);
        }
    }

    // Actually rooted forest
    class Tree extends Graph {

        public Tree(int n, int m) {
            super(n, m);
        }

        public int getHeight(int i) {
            int res = 0;
            for (Integer j: adj[i]) {
                res = Math.max(res, getHeight(j) + 1);
            }
            return res;
        }
    }

    class FenwickTree {
        int n;
        int tree[];

        public FenwickTree() {

        }

        public FenwickTree(int maxn) {
            n = maxn;
            tree = new int[maxn + 10];
        }

        public void add(int i, int x) {
            while (i <= n) {
                tree[i] += x;
                i += i & (-i);
            }
        }

        public void add(int i) {
            add(i, 1);
        }

        public int get(int i) {
            int res = 0;
            while (i > 0) {
                res += tree[i];
                i -= i & (-i);
            }
            return res;
        }
    }

    IOManager ioManager;

    Main() {
        ioManager = new IOManager();
    }

    Main(String file) throws FileNotFoundException {
        ioManager = new IOManager(file);
    }

    class Node {
        Node l, r, par;
        int cnt;

        Node() {
            l = r = par = null;
            cnt = 0;
        }
    }

    int n;
    Node root;
    final int maxbit = 30;

    void add(int x, int d) {
        Node p = root;
        for (int i = maxbit; i >= 0; --i) {
            int y = (x >> i) & 1;
            if (y == 0) {
                if (p.l == null) {
                    p.l = new Node();
                    p.l.par = p;
                }
            } else {
                if (p.r == null) {
                    p.r = new Node();
                    p.r.par = p;
                }
            }
            Node q;
            if (y == 0)
                q = p.l;
            else
                q = p.r;
            p = q;
        }
        p.cnt += d;
        while (p.par != null) {
            p = p.par;
            p.cnt += d;
        }
    }

    int get(int x, int l) {
        int res = 0;
        Node p = root;
        for (int i = maxbit; i >= 0; --i) {
            int li = (l >> i) & 1;
            int xi = (x >> i) & 1;
            if (li == 0) {
                Node q = xi == 0 ? p.l : p.r;
                if (q == null)
                    return res;
                p = q;
            } else {
                Node q = xi == 0 ? p.r : p.l;
                Node q2 = xi == 0 ? p.l : p.r;
                res += q2 == null ? 0 : q2.cnt;
                if (q == null)
                    return res;
                p = q;
            }
        }
        return res;
    }

    void solve() throws IOException {
        root = new Node();
        n = ioManager.nextInt();
        for (int i = 1; i <= n; ++i) {
            int type = ioManager.nextInt();
            if (type == 1) {
                int x = ioManager.nextInt();
                add(x, 1);
            } else if (type == 2) {
                int x = ioManager.nextInt();
                add(x, -1);
            } else {
                int x = ioManager.nextInt();
                int l = ioManager.nextInt();
                ioManager.writeLine(get(x, l));
            }
        }
    }

    void close() {
        ioManager.close();
    }

    public static void main(String args[]) throws IOException {
        Main solver;
        if (!"true".equals(System.getProperty("ONLINE_JUDGE"))) {
            solver = new Main("input.txt");
        } else {
            solver = new Main();
        }
        solver.solve();
        solver.close();
    }
}