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.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
	
	
	 public class Palindrome {
	
		static double eps=(double)1e-6;
		static long mod=(int)1e9+7;
		public static void main(String args[]){
			InputReader in = new InputReader(System.in);
			OutputStream outputStream = System.out;
			PrintWriter out = new PrintWriter(outputStream);
			//Scanner sc=new Scanner(System.in);
			//----------My Code----------
				int n=in.nextInt();
				HashMap<Integer,Integer> hm=new HashMap<Integer, Integer>();
				TrieNode root=new TrieNode();
				String tmp="";
				while(tmp.length()<32)
					tmp+="0";
				root.a[0]=new TrieNode();
				insert(tmp,root);
				for(int i=0;i<n;i++)
				{
					
					String h=in.next();
					int a=in.nextInt();
					if(h.equals("+"))
					{
						String bn=((Integer)(a)).toBinaryString(a);
						while(bn.length()<32)
						bn="0"+bn;
						//System.out.println(bn);
						if(!hm.containsKey(a)){
							hm.put(a, 1);
							insert(bn,root);
							//printSorted(root, "");
						}
						else
							hm.put(a, hm.get(a)+1);
						
						
					}
					else if(h.equals("-"))
					{
						String bn=((Integer)(a)).toBinaryString(a);
						while(bn.length()<32)
						bn="0"+bn;
						if(hm.get(a)==1){
							remove(bn,root);
							hm.remove(a);
						}
						else
							hm.put(a, hm.get(a)-1);
						
					}
					else if(h.equals("?"))
					{
						String bn=((Integer)(a)).toBinaryString(a);
						while(bn.length()<32)
						bn="0"+bn;
						String jj=max(bn,root);
						long ans=0;
						//System.out.println(jj);
						for(int j=1;j<jj.length();j++){
							ans+=(jj.charAt(j)-'0')*Math.pow(2,jj.length()-j-1);
						}
					System.out.println(ans);
					}
					
				}
			//---------------The End------------------
			out.close();
		}
		
		
			static class TrieNode{
				boolean isLeaf;
				int b;
				TrieNode[] a=new TrieNode[2];
			}
			
			static void insert(String key,TrieNode root){
				TrieNode temp=root;
				for(int i=0;i<key.length();i++){
					if(temp.a[key.charAt(i)-'0']==null){
						temp.a[key.charAt(i)-'0']=new TrieNode();
					}
					temp.a[key.charAt(i)-'0'].b+=1;
					temp=temp.a[key.charAt(i)-'0'];
				}
				temp.isLeaf=true;
			}
			static boolean search(String key,TrieNode root){
				TrieNode temp=root;
				for(int i=0;i<key.length();i++){
					if(temp.a[key.charAt(i)-'0']==null)
						return false;
					temp=temp.a[key.charAt(i)-'0'];
				}
				return (temp.isLeaf);
			}
			static String max(String key,TrieNode root){
				TrieNode temp=root;
				String res="";
				for(int i=0;i<key.length();i++){
					
					if(temp.a[(key.charAt(i)-'0')^1]!=null){
					//	System.out.println("Hetr");
					temp=temp.a[(key.charAt(i)-'0')^1];
					res+="1";
					}
					else if(temp.a[(key.charAt(i)-'0')]!=null){
						//System.out.println("Hetr");
						temp=temp.a[(key.charAt(i)-'0')];
						res+="0";
					}
				}
			//	System.out.println(res+"jj");
				return res;
			}
			static void remove(String key,TrieNode root){
				TrieNode temp=root;
				for(int i=0;i<key.length();i++){
					if(temp==null)
						return;
				  if(temp.a[(key.charAt(i)-'0')]!=null&&temp.a[key.charAt(i)-'0'].b>1){
						
						temp.a[(key.charAt(i)-'0')].b--;
						
					
					temp=temp.a[(key.charAt(i)-'0')];
				}
				else
				{
					temp.a[key.charAt(i)-'0']=null;
					return;
				}
				}
				if(temp!=null)
					temp.isLeaf=false;
			}
			
			public static void printSorted(TrieNode node, String s) {
		        for (int ch = 0; ch < node.a.length; ch++) {
		            TrieNode child = node.a[ch];
		            if (child != null)
		                printSorted(child, s + (ch));
		        }
		        if (node.isLeaf) {
		            System.out.println(s);
		        }
		    }
		private static void permutation(String prefix, String str,HashSet<String> hs) {
		    int n = str.length();
		    if (n == 0) hs.add(prefix);
		    else {
		        for (int i = 0; i < n; i++)
		            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n),hs);
		    }
		}
		static int[][] floydWarshall(int graph[][],int V)
	    {
	        int dist[][] = new int[V][V];
	        int i, j, k;
	 
	        /* Initialize the solution matrix same as input graph matrix.
	           Or we can say the initial values of shortest distances
	           are based on shortest paths considering no intermediate
	           vertex. */
	        for (i = 0; i < V; i++)
	            for (j = 0; j < V; j++)
	                dist[i][j] = graph[i][j];
	 
	        /* Add all vertices one by one to the set of intermediate
	           vertices.
	          ---> Before start of a iteration, we have shortest
	               distances between all pairs of vertices such that
	               the shortest distances consider only the vertices in
	               set {0, 1, 2, .. k-1} as intermediate vertices.
	          ----> After the end of a iteration, vertex no. k is added
	                to the set of intermediate vertices and the set
	                becomes {0, 1, 2, .. k} */
	        for (k = 0; k < V; k++)
	        {
	            // Pick all vertices as source one by one
	            for (i = 0; i < V; i++)
	            {
	                // Pick all vertices as destination for the
	                // above picked source
	                for (j = 0; j < V; j++)
	                {
	                    // If vertex k is on the shortest path from
	                    // i to j, then update the value of dist[i][j]
	                    if (dist[i][k] + dist[k][j] < dist[i][j])
	                        dist[i][j] = dist[i][k] + dist[k][j];
	                }
	            }
	        }
	return dist;
	    }
		static int recursiveBinarySearch(int[] sortedArray, int start, int end, int key) {
	
			if (start <= end) {
				int mid = start + (end - start) / 2; 
				if (key < sortedArray[mid]) {
					return recursiveBinarySearch(sortedArray, start, mid-1, key);
	
				} else if (key > sortedArray[mid]) {
					return recursiveBinarySearch(sortedArray, mid+1, end , key);
	
				} else {
					return mid;  
				}
			}
			return -(start + 1); 
		}
	
		static long modulo(long a,long b,long c) {
			long x=1;
			long y=a;
			while(b > 0){
				if(b%2 == 1){
					x=(x*y)%c;
				}
			
				y = (y*y)%c; // squaring the base
				b /= 2;
			}
			return  x%c;
		}
		
		
		static long gcd(long x, long y)
		
		{
			long r=0, a, b;
			a = (x > y) ? x : y; // a is greater number
			b = (x < y) ? x : y; // b is smaller number
			r = b;
			while(a % b != 0)
			{
				r = a % b;
				a = b;
				b = r;
			}
			return r;
		}
		static class pair implements Comparable<pair> {
			int x;
			int y;
			//int i;
			pair(int  xx,int yy){
				
				x=xx;
				y=yy;
				//i=ii;
			}
			@Override
			public int compareTo(pair arg0) {
				return Long.compare(this.x, arg0.x);
			}
		
		}
		static class InputReader {
			public BufferedReader reader;
			public StringTokenizer tokenizer;
	
			public InputReader(InputStream inputstream) {
				reader = new BufferedReader(new InputStreamReader(inputstream));
				tokenizer = null;
			}
	
			public String nextLine(){
				String fullLine=null;
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					try {
						fullLine=reader.readLine();
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
					return fullLine;
				}
				return fullLine;
			}
			public String next() {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					try {
						tokenizer = new StringTokenizer(reader.readLine());
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
				}
				return tokenizer.nextToken();
			}
			public long nextLong() {
				return Long.parseLong(next());
			}
			public int nextInt() {
				return Integer.parseInt(next());
			}
		}
	} 