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.util.*;
import java.io.*;
/*
3
10 2
0.25 0.25 0.25 0.25
0.25 0.25 0.25 0.25
64 3
0.3 0.4 0.0 0.3
1.0 0.0 0.0 0.0
0.2 0.2 0.2 0.4
3 2
0.5 0.17 0.17 0.16
0.5 0.25 0.25 0.0
 */
public class d 
{
	public static void main(String[] arg) throws IOException
	{
		new d();
	}
	public String getBinary(int num)
	{
		String ret = Integer.toBinaryString(num);
		while(ret.length() < 64) ret = '0'+ret;
		return ret;
	}
	public d() throws IOException
	{
		FastScanner in = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int Q = in.nextInt();
		Trie trie = new Trie("01");
		trie.add(getBinary(0));
		while(Q-- > 0)
		{
			String op = in.next();
			int val = in.nextInt();
			if(op.equals("+"))
			{
				trie.add(getBinary(val));
			}
			else if(op.equals("-"))
			{
				trie.delete(getBinary(val));
			}
			else
			{
				String s = getBinary(val);
				String ret = solve(0, s, trie.root);
				while(ret.length() < 64) ret = ret+'0';
				out.println(Integer.parseInt(ret, 2));
			}
			//trie.print();
			//System.out.println();
		}
		in.close(); out.close();
	}
	String solve(int idx, String s, Node head)
	{
		if(idx >= 64)
		{
			if(head.count > 0) return "";
			else return null;
		}
		if(head.count == 0) return null;
		if(s.charAt(idx) == '0')
		{
			if(head.adjList[1] != null)
			{
				String temp = solve(idx+1, s, head.adjList[1]);
				if(temp != null) return '1'+temp;
			}
			if(head.adjList[0] != null)
			{
				String temp = solve(idx+1, s, head.adjList[0]);
				if(temp != null) return '0'+temp;
			}
		}
		else if(s.charAt(idx) == '1')
		{
			if(head.adjList[0] != null)
			{
				String temp = solve(idx+1, s, head.adjList[0]);
				if(temp != null) return '1'+temp;
			}
			if(head.adjList[1] != null)
			{
				String temp = solve(idx+1, s, head.adjList[1]);
				if(temp != null) return '0'+temp;
			}
		}
		return "";
	}
	class Node
	{
		int count;
		Node[] adjList;
		public Node(int size)
		{
			count = 0;
			adjList = new Node[size];
		}
	}
	class Trie 
	{
		Node root;
		HashMap<Character, Integer> map;
		String alphabet;
		// Lets assume the alphabet has distinct elements
		public Trie(String alphabet)
		{
			map = new HashMap<Character, Integer>();
			for(int i = 0; i < alphabet.length(); i++)
			{
				map.put(alphabet.charAt(i), i);
			}
			root = new Node(map.size());
			this.alphabet = alphabet;
		}
		public void add(String word)
		{
			add(0, word, root);
		}
		public void add(int index, String word, Node head)
		{
			if(index == word.length())
			{
				head.count++;
				return;
			}	
			int i = map.get(word.charAt(index));
			if(head.adjList[i] == null) head.adjList[i] = new Node(map.size());
			add(index+1, word, head.adjList[i]);
			head.count++;
		}
		public void delete(String word)
		{
			delete(0, word, root);
		}
		public void delete(int index, String word, Node head)
		{
			if(index == word.length())
			{
				if(head.count > 0) head.count--;
				return;
			}
			int i = map.get(word.charAt(index));
			if(head.adjList[i] == null) return;
			delete(index+1, word, head.adjList[i]);
			head.count--;
		}
		public String extractTree()
		{
			StringBuilder sb = new StringBuilder();
			for(int i = 0; i < root.adjList.length; i++)
			{
				if(root.adjList[i] == null) continue;
				extractTree(root.adjList[i], alphabet.charAt(i)+"", sb);
			}
			return sb.toString();
		}
		public void extractTree(Node head, String word, StringBuilder sb)
		{
			if(head.count > 0)
			{
				sb.append(word+" "+head.count+" ");
			}
			for(int i = 0; i < alphabet.length(); i++)
			{
				if(head.adjList[i] == null) continue;
				extractTree(head.adjList[i], word+alphabet.charAt(i), sb);
			}
		}
		public void print()
		{
			for(int i = 0; i < alphabet.length(); i++)
			{
				if(root.adjList[i] == null) continue;
				print(root.adjList[i], alphabet.charAt(i)+"");
			}
		}
		public void print(Node head, String word)
		{
			if(head.count > 0)
			{
				System.out.println(word + " " + head.count);
			}
			for(int i = 0; i < head.adjList.length; i++)
			{
				if(head.adjList[i] == null) continue;
				print(head.adjList[i], word+alphabet.charAt(i));
			}
		}
	}
	class FastScanner
	{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in)
		{
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer("");
		}
		public String next() throws IOException
		{
			while(!st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int nextInt() throws IOException
		{
			return Integer.parseInt(next());
		}
		public void close() throws IOException
		{
			br.close();
		}
	}
}
