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.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Writer;

public class Main {
	
	public static void main(String[] args) throws Exception {
		BufferedReader inp = new BufferedReader (new InputStreamReader(System.in));
		Writer writer = new PrintWriter(System.out);
		int c = Integer.parseInt(inp.readLine());
		Trie t = new Trie();
		t.insert(toBinary(0));
		
		String[] input;
		int n;
		
		while(c-- > 0) {
			input = inp.readLine().split(" ");
			n = Integer.parseInt(input[1]);
			switch(input[0]) {
			case "+": t.insert(toBinary(n)); break;
			case "-": t.remove(toBinary(n)); break;
			case "?": writer.write(t.query(n, toInverseBin(n)) + System.getProperty("line.separator")); break;
			}
		}
		writer.flush();
	}
	
	static String toBinary(int x) {
		return toBinary(x, 30);
	}

	static String toBinary(int x, int length) {
		String bin = Integer.toBinaryString(x);
		int paddingLength = 30 - bin.length();
		String padding = "";
		for(int i = 0; i < paddingLength; i++) padding += "0";
		return padding + bin;
	}
	
	static String toInverseBin(int x) {
		String bin = toBinary(x);
		int binLength = bin.length();
		String inverseBin = "";
		for(int i = 0; i < binLength; i++) inverseBin += (bin.charAt(i) == '0') ? "1" : "0";
		return inverseBin;
	}
}

class Node {
	int count;
	Node[] children;
	
	Node() {
		this(0);
	}
	
	Node(int count) {
		this.count = count;
		children = new Node[2];
	}
}

class Trie {
	Node head;
	
	Trie() {
		head = new Node();
	}
	
	void insert(String bin) {
		Node current = head;
		int binLength = bin.length();
		int x;
		for(int i = 0; i < binLength; i++) {
			x = Character.getNumericValue(bin.charAt(i));
			if(current.children[x] == null) {
				current.children[x] = new Node();
			}
			current = current.children[x];
			current.count++;
		}
	}
	
	void remove(String bin) {
		Node current = head;
		int binLength = bin.length();
		int x;
		for(int i = 0; i < binLength; i++) {
			x = Character.getNumericValue(bin.charAt(i));
			current = current.children[x];
			current.count--;
		}
	}
	
	int query(int n, String inverseBin) {
		String bin = "";
		Node current = head;
		int inverseBinLength = inverseBin.length();
		int x;
		for(int i = 0; i < inverseBinLength; i++) {
			x = Character.getNumericValue(inverseBin.charAt(i));
			if(current.children[x] != null && current.children[x].count > 0) {
				bin += x;
				current = current.children[x];
			} else {
				x = (x+1) % 2;
				bin += x;
				current = current.children[x];
			}
		}
		int m = Integer.parseInt(bin, 2);
		return m^n;
	}	
}