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.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class VasiliysMultiset {
	
	
	public static class Node {
		Node[] children = new Node[2];
		int count = 0;
	}
	
	
	public static void search(int key, Node start) {
		Node curr = start;
		boolean found = false;
		char[] num = Integer.toBinaryString(key).toCharArray();
		for(int i = 0; i < 31 - num.length; i++)
			curr = curr.children[0];
		for(int i = 0; i < num.length; i++) {
			if(curr.children[num[i] - '0'] != null)
				curr = curr.children[num[i] - '0'];
			else {
				found = true;
				break;
			}
		}
		System.out.println(found);
	}
	
	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(System.out);
		StringTokenizer st;
		char[] charBinNum;
		Node root = new Node();
		Node curr = root;
		for(int i = 0 ; i < 31; i++) {
			curr.children[0] = new Node();
			curr.count++;
			curr = curr.children[0];
		}
		curr.count++;
		int n = Integer.parseInt(br.readLine());
		for(int i = 0; i < n; i++) {
			st = new StringTokenizer(br.readLine());
			char op = st.nextToken().charAt(0);
			if(op == '+') {
				curr = root;
				charBinNum = Integer.toBinaryString(Integer.parseInt(st.nextToken())).toCharArray();
				int diff = 31 - charBinNum.length;
				for(int j = 0; j < diff; j++) {
					curr.count++;
					curr = curr.children[0];
				}
				for(int j = 0; j < charBinNum.length; j++) {
					if(curr.children[charBinNum[j] - '0'] == null) {
						curr.children[charBinNum[j] - '0'] = new Node();
					}
					curr.count++;
					curr = curr.children[charBinNum[j] - '0'];
				}
				curr.count++;
			}
			else {
				if(op == '-') {
					curr = root;
					charBinNum = Integer.toBinaryString(Integer.parseInt(st.nextToken())).toCharArray();
					int diff = 31 - charBinNum.length;
					boolean found = false;
					for(int j = 0; j < diff; j++) {
						Node target = curr.children[0];
						target.count--;
						if(target.count == 0) {
							found = true;
							curr.children[0] = null;
							break;
						}
						curr = curr.children[0];
					}
					for(int j = 0; j < charBinNum.length - 1; j++) {
						Node target = curr.children[charBinNum[j] - '0'];
						target.count--;
						if(target.count == 0) {
							found = true;
							curr.children[charBinNum[j] - '0'] = null;
							break;
						}
						curr = curr.children[charBinNum[j] - '0'];
					}
					if(!found) {
						Node target = curr.children[charBinNum[charBinNum.length - 1] - '0'];
						target.count--;
	//					System.out.println(target.count);
						curr.children[charBinNum[charBinNum.length - 1] - '0'] = target.count == 0? null :target;
					}
//					Node test = root;
//					diff = 31 - 4;
//					for(int j = 0; j < diff; j++)
//						test = test.children[0];
//					for(int j = 0; j < charBinNum.length; j++) {
//						test = test.children[charBinNum[j] - '0'];
//						System.out.println(test);
//					}
				}
				else {
					curr = root;
					charBinNum = Integer.toBinaryString(Integer.parseInt(st.nextToken())).toCharArray();
					StringBuilder sb = new StringBuilder();
//					String otherNum = "";
					int diff = 31 - charBinNum.length;
					for(int j = 0; j < diff; j++) {
						if(curr.children[1] != null) {
							sb.append('1');
//							otherNum += '1';
							curr = curr.children[1];
						}
						else {
							sb.append('0');

//							otherNum += '0';
							curr = curr.children[0];
						}
					}
					for(int j = 0; j < charBinNum.length; j++) {
						if(curr.children[1 - (charBinNum[j] - '0')] != null) {
							sb.append('1');

//							otherNum += (1 - (charBinNum[j] - '0'));
							curr = curr.children[1 - (charBinNum[j] - '0')];
						}
						else {
							sb.append(0);

//							otherNum += (charBinNum[j] - '0');
							curr = curr.children[charBinNum[j] - '0'];
						}
					}
					out.println(Integer.parseInt(sb.toString(), 2));
//					System.out.println(Integer.parseInt(otherNum, 2));
				}
			}
		}
//		search(9, root);
		br.close();
		out.close();
	}
	
}

//? 1
//+ 1
//+ 7
//? 2
//+ 3
//? 1
//? 6
//+ 4
//+ 8
//- 8
//+ 6
//+ 6
//- 6
//? 3
//+ 2
//? 7

