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>.
import java.io.*;
import java.util.*;

/**
 * This looks like a radix-tree.
 * Can I code it?
 */
public class Multiset
{
    static class Node {
        Node zero, one;
        int count;

        int best(int x, int depth) {
            if (depth < 0)
                return 0;

            if (zero != null && one != null) {
                if ((x & (1<<depth)) == 0)
                    return (1<<depth) + one.best(x, depth-1);
                else
                    return (1<<depth) + zero.best(x, depth-1);
            }

            if (zero == null) {
                if ((x & (1<<depth)) == 0)
                    return (1<<depth) + one.best(x, depth-1);
                else
                    return one.best(x, depth-1);
            }

            if (one == null) {
                if ((x & (1<<depth)) != 0)
                    return (1<<depth) + zero.best(x, depth-1);
                else
                    return zero.best(x, depth-1);
            }
            throw new Error();
        }

        boolean remove(int x, int depth) {
            if (depth < 0) {
                return --count == 0;
            } else {
                if ((x & (1<<depth)) == 0) {
                    if (zero.remove(x, depth - 1))
                        zero = null;
                } else {
                    if (one.remove(x, depth - 1))
                        one = null;
                }
                return zero == null && one == null;
            }
        }

        void add(int x, int depth) {
            if (depth < 0) {
                count++;
            } else {
                if ((x & (1<<depth)) == 0) {
                    if (zero == null) {
                        zero = new Node();
                    }
                    zero.add(x, depth - 1);
                } else {
                    if (one == null) {
                        one = new Node();
                    }
                    one.add(x, depth - 1);
                }
            }
        }
        @Override
        public String toString() { if (zero != null || one != null) return "(z:" + zero + ";o:" + one + ")";  else return "v="+count; }
    }

    static class Tree {
        Node root = new Node();
        Tree() {
            add(0);
        }

        void add(int x) {
            root.add(x, 30);
        }
        void remove(int x) {
            root.remove(x, 30);
        }
        int best(int x) {
            return root.best(x, 30);
        }
    }

    public static void main(String []av) {
        PrintWriter out = new PrintWriter(System.out); 
        Scanner s = new Scanner();
        int q = s.nextInt();
        Tree t = new Tree();
        for (int i = 0; i < q; i++) {
            String op = s.next();
            int x = s.nextInt();
            if (op.charAt(0) == '+') {
                t.add(x);
                // System.err.println(t.root);
            } else
            if (op.charAt(0) == '-') {
                t.remove(x);
            } else
            if (op.charAt(0) == '?') {
                out.println(t.best(x));
            } else
                throw new Error();
        }
        out.flush();
    }

    //-----------Scanner class for faster input----------
    /* Provides similar API as java.util.Scanner but does not
     * use regular expression engine.  
     */
    public static class Scanner {
        BufferedReader br;
        StringTokenizer st;

        public Scanner(Reader in) {
            br = new BufferedReader(in);
        }

        public Scanner() { this(new InputStreamReader(System.in)); }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() { return Integer.parseInt(next()); }
        long nextLong() { return Long.parseLong(next()); }
        double nextDouble() { return Double.parseDouble(next()); }

        // Slightly different from java.util.Scanner.nextLine(),
        // which returns any remaining characters in current line,
        // if any.  
        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
}
