Author has gone out of the stories about Vasiliy, so here is just a formal task description.

You are given q queries and a multiset A, initially containing only integer 0. There are three types of queries:

  1. "+ x" — add integer x to multiset A.
  2. "- x" — erase one occurrence of integer x from multiset A. It's guaranteed that at least one x is present in the multiset A before this query.
  3. "? x" — you are given integer x and need to compute the value <image>, i.e. the maximum value of bitwise exclusive OR (also know as XOR) of integer x and some integer y from the multiset A.



Multiset is a set, where equal elements are allowed.

Input

The first line of the input contains a single integer q (1 ≤ q ≤ 200 000) — the number of queries Vasiliy has to perform.

Each of the following q lines of the input contains one of three characters '+', '-' or '?' and an integer xi (1 ≤ xi ≤ 109). It's guaranteed that there is at least one query of the third type.

Note, that the integer 0 will always be present in the set A.

Output

For each query of the type '?' print one integer — the maximum value of bitwise exclusive OR (XOR) of integer xi and some integer from the multiset A.

Example

Input

10
+ 8
+ 9
+ 11
+ 6
+ 1
? 3
- 8
? 3
? 8
? 11


Output

11
10
14
13

Note

After first five operations multiset A contains integers 0, 8, 9, 11, 6 and 1.

The answer for the sixth query is integer <image> — maximum among integers <image>, <image>, <image>, <image> and <image>.
/*-
 * Codeforces problem :
 * http://codeforces.com/problemset/problem/706/D
 *
 * The first line of the input contains a single integer q (1 ≤ q ≤ 200 000)
 * — the number of queries Vasiliy has to perform.
 * Each of the following q lines of the input contains one of three characters
 * '+', '-' or '?' and an integer xi (1 ≤ xi ≤ 109). It's guaranteed that there
 * is at least one query of the third type.
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/**
 * @author Karthik Venkataraman
 * @email kafy83@gmail.com
 */
public class VasiliyMultiset {

    class InputReader {

        private static final int INPUT_KB = 1024;
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), INPUT_KB);
        }

        String readNext() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException ex) {
                    throw new IllegalArgumentException(ex);
                }
            }
            return tokenizer.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(readNext());
        }
    }

    class Trie {

        private static final int BIT_LEN = 30;
        private int n;
        private Node root;

        Trie() {
            root = new Node();
        }

        class Node {

            private Integer key;
            private Integer value;
            private Node[] nodes;

            Node() {
                nodes = new Node[2];
            }

            Node(int key, int value) {
                this.key = key;
                this.value = value;
            }
        }

        private int getBit(int key, int i) {
            return ((1 << i) & key) == 0 ? 0 : 1;
        }

        private void insert(int key) {
            Node x = root;
            for (int i = BIT_LEN; i >= 0; i--) {
                int idx = getBit(key, i);
                if (x.nodes[idx] == null) {
                    x.nodes[idx] = new Node();
                }
                x = x.nodes[idx];
            }
            if (x.key == null) {
                x.key = key;
                x.value = 1;
                n++;
                return;
            }
            x.value++;
        }

        private void delete(int key) {
            root = delete(key, root, BIT_LEN);
        }

        private Node delete(int key, Node x, int d) {
            if (x == null) {
                return null;
            }

            if (d == -1) {
                if (x.value > 0) {
                    x.value--;
                } else {
                    x.value = null;
                }
                n--;
            } else {
                int idx = getBit(key, d);
                x.nodes[idx] = delete(key, x.nodes[idx], d - 1);
            }

            if (x.value != null && x.value > 0) {
                return x;
            }

            for (int i = 0; i < 2; i++) {
                if (x.nodes[i] != null) {
                    return x;
                }
            }

            return null;
        }

        private int maxXorTuple(int query) {
            Node x = root;
            for (int i = BIT_LEN; i >= 0; i--) {
                int idx = getBit(query, i);
                int inidx = idx ^ 1;
                x = x.nodes[inidx] != null ? x.nodes[inidx] : x.nodes[idx];
            }
            return query ^ x.key;
        }
    }

    private Trie trie;
    private InputReader sc;

    private void compute() {
        sc = new InputReader(System.in);
        trie = new Trie();
        int q = sc.nextInt();
        trie.insert(0);
        while (q-- > 0) {
            String op = sc.readNext();
            switch (op) {
                case "+":
                    trie.insert(sc.nextInt());
                    break;
                case "-":
                    trie.delete(sc.nextInt());
                    break;
                case "?":
                    System.out.println(trie.maxXorTuple(sc.nextInt()));
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected character");
            }
        }
    }

    public static void main(String... args) {
        VasiliyMultiset vm = new VasiliyMultiset();
        vm.compute();
    }
}