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.util.*;

public class problem1 {

	static class Trie {
	
		class Node {
			int end;
			Node[] next, prev;
		
			Node() {
				next = new Node[2];
				prev = new Node[2];
			}
		}
		
		Node root;
		
		Trie() {
			root = new Node();
			insert(new int[32]);
		}
	
		void insert(int ... s) {
			Node cur = root;
			for (int i = 0; i < 32; ++i) {
				if (cur.next[s[i]] == null) {
					cur.next[s[i]] = new Node();
					cur.next[s[i]].prev[s[i]] = cur;
				}
				cur = cur.next[s[i]];
			}
			++cur.end;
		}
		
		void erase(int ... s) {
			Node cur = search(s);
			--cur.end;
			if (cur.end == 0) {
				cur = cur.prev[s[31]];
				for (int i = 31; i >= 1; --i) {
					cur.next[s[i]] = null;
					if (cur.next[1 - s[i]] != null) break;
					cur = cur.prev[s[i - 1]];
				}
			}
		}
		
		Node search(int ... s) {
			Node cur = root;
			for (int i = 0; i < 32; i++) cur = cur.next[s[i]];
			return cur;
		}
		
		int searchMax(int ... s) {
			Node cur = root;
			int res = 0;
			for (int i = 0; i < 32; ++i) {
				int nextIdx = 1 - s[i];
				if (cur.next[1 - s[i]] == null) {
					if (cur.next[s[i]] == null) return res;
					cur = cur.next[s[i]];
				} else {
					res += 1 << (31 - i);
					cur = cur.next[1 - s[i]];
				}
			}
			return res;
		}
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		int q = Integer.parseInt(reader.readLine());
		Trie trie = new Trie();
		while(q-- > 0) {
			String[] line = reader.readLine().split(" ");
			int x = Integer.parseInt(line[1]);
			int[] s = new int[32];
			for(int i = 31, j = x; i >= 0 && j > 0; --i, j >>= 1) s[i] = j & 1;
			if (line[0].equals("+")) trie.insert(s);
			else if (line[0].equals("-")) trie.erase(s);
			else System.out.println(trie.searchMax(s));
		}
	}
}