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>.
/**
 * Created by abhishek on 8/12/2016.
 */
import java.util.*;
import java.io.*;
public class Major {
    static void update(int temp, Node tree) {
        Node current = tree;
        for (int i = 30; i >= 0; i--) {
            int a = ((1 << i) & temp) > 0 ? 1 : 0;
            current = current.getChildIfNotExistCreate(a, 0);
        }
    }

    static void update1(int temp, Node tree) {
        Node current = tree;
        for (int i = 30; i >= 0; i--) {
            int a = ((1 << i) & temp) > 0 ? 1 : 0;
            current = current.getChildIfNotExistCreate(a, 1);
            if (current == null)
                break;
        }
    }
    static int findMax(int temp,Node tree){
        Node current = tree;
        int ans = 0;
        Node prev = tree;
        for(int i = 30;i >= 0;i--){
            int a = ((1 << i) & temp) > 0 ? 1 : 0;
            prev = current;
            //if(current == null)break;
            current = current.getChild(1 - a);
            if(current != null)
                ans += (1 << i);
            else current = prev.getChild(a);
        }
        return ans;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int q = Integer.parseInt(br.readLine());
        StringTokenizer st;
        TreeMap<Integer, Integer> map = new TreeMap<>();
        map.put(0, 1);
        StringBuilder sb = new StringBuilder();
        Node tree = new Node(0);
        update(0,tree);
        for (int i = 1; i <= q; i++) {
            st = new StringTokenizer(br.readLine());
            String fir = st.nextToken();
            int temp = Integer.parseInt(st.nextToken());
            if (fir.charAt(0) == '+') {
                if (!map.containsKey(temp))
                    map.put(temp, 1);
                 else map.put(temp, map.get(temp) + 1);
                update(temp, tree);
            }
            else if (fir.charAt(0) == '-') {
                map.put(temp, map.get(temp) - 1);
                if (map.get(temp) == 0)
                    map.remove(temp);
                    update1(temp,tree);
                }
            else {
                sb.append(findMax(temp,tree));
                sb.append('\n');
            }
        }
        System.out.println(sb);
    }

    static class Node {
        int cnt;
        Node[] node = new Node[2];

        Node(int cnt) {
            this.cnt = cnt;
        }

        Node getChildIfNotExistCreate(int a, int val) {
            if (val == 0) {
                if (node[a] == null)
                    node[a] = new Node(1);
                else node[a].cnt += 1;
            }
            if (val == 1) {
                node[a].cnt -= 1;
                if (node[a].cnt == 0)
                    node[a] = null;
            }
            return node[a];
            }
        Node getChild(int a){
            if(node[a] != null)
                return node[a];
            return null;
        }
        }
}
