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;

public class Codeforces{
	
	static Node root;
	
	public static void main(String[] args) throws IOException{		
		Scan scan = new Scan();
		int n = scan.nextInt();
		root = new Node();
		add(toBinary(0));
		for(int i = 0; i < n; i++){
			String s = scan.nextLine();
			if(s.charAt(0) == '+') add(toBinary(Integer.parseInt(s.substring(2))));
			else if(s.charAt(0) == '-') remove(toBinary(Integer.parseInt(s.substring(2))));
			else if(s.charAt(0) == '1') print(root, 30, 0);
			else query(toBinary(Integer.parseInt(s.substring(2))));
		}
	}
	
	public static void print(Node current, int index, int number){
		if(index == -1) System.out.println(number + "   " + current.children);
		if(current.child[0] != null)
			print(current.child[0], index - 1, number);
		if(current.child[1] != null)
			print(current.child[1], index - 1, number + (1 << index));		
	}
	
	public static void query(int[] s){
		Node current = root;
		int number = 0;
		for(int i = 30; i >= 0; i--){
			if(current.child[s[i] ^ 1] != null){
				number += (1 << i);
				current = current.child[s[i] ^ 1];
			}
			else{
				current = current.child[s[i]];
			}
		}
		System.out.println(number);
	}
	
	public static void remove(int[] s){
		Node current = root;
		current.children--;
		for(int i = 30; i >= 0; i--){
			current.child[s[i]].children--;
			if(current.child[s[i]].children == 0){
				current.child[s[i]] = null;
				break;
			}
			current = current.child[s[i]];
		}
	}
	
	public static void add(int[] s){
		Node current = root;
		for(int i = 30; i >= 0; i--){
			current.children++;
			if(current.child[s[i]] == null) current.child[s[i]] = new Node();
			current = current.child[s[i]];
		}
		current.children++;
	}
	
	public static int[] toBinary(int n){
		int[] result = new int[31];
		for(int i = 0; i < 31; i++){
			result[i] = (n & 1);
			n /= 2;
		}
		return result;
	}
	
	public static class Node{
		int children = 0;
		Node[] child = new Node[2];
	}
	
	public static class Scan{		
		BufferedReader br;	
		String[] s;
		String str;
		int strIndex;
		int index;
		public Scan(){
			br = new BufferedReader(new InputStreamReader(System.in));
			index = 0;
			s = new String[0];
			str = "a";
			strIndex = 1;
		}
		public String nextLine() throws IOException{
			return br.readLine();
		}
		public char nextChar() throws IOException{
			if(strIndex == str.length()){
				str = br.readLine();
				strIndex = 0;
			}
			strIndex++;
			return str.charAt(strIndex - 1);
		}
		public char[] nextCharArray() throws IOException{
			str = br.readLine();
			strIndex = str.length();
			return str.toCharArray();
		}
		public int[] nextIntArray() throws IOException{
			s = br.readLine().split(" ");
			int[] result = new int[s.length];
			for(int i = 0; i < s.length; i++) result[i] = Integer.parseInt(s[i]);
			index = s.length;
			return result;
		}
		public long[] nextLongArray() throws IOException{
			s = br.readLine().split(" ");
			long[] result = new long[s.length];
			for(int i = 0; i < s.length; i++) result[i] = Long.parseLong(s[i]);
			index = s.length;
			return result;
		}
		public double[] nextDoubleArray() throws IOException{
			s = br.readLine().split(" ");
			double[] result = new double[s.length];
			for(int i = 0; i < s.length; i++) result[i] = Double.parseDouble(s[i]);
			index = s.length;
			return result;
		}
		public int nextInt() throws IOException{
			if(index == s.length){
				s = br.readLine().split(" ");
				index = 0;
			}
			index++;
			return Integer.parseInt(s[index - 1]);			
		}
		public long nextLong() throws IOException{
			if(index == s.length){
				s = br.readLine().split(" ");
				index = 0;
			}
			index++;
			return Long.parseLong(s[index - 1]);			
		}
		public double nextDouble() throws IOException{
			if(index == s.length){
				s = br.readLine().split(" ");
				index = 0;
			}
			index++;
			return Double.parseDouble(s[index - 1]);
		}
	}
}





