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.*;
import java.math.*;


public class Main implements Runnable {
	public BufferedReader in;
	public PrintWriter out;
	public StringTokenizer tok;
	
	
	public void solve() throws Exception {
		int q = nextInt();
		Node root = new Node();
		insert(root, 0, 30);
		for (int qq = 0; qq < q; ++qq) {
			String s = next();
			if (s.equals("+")) {
				insert(root, nextInt(), 30);
			} else if (s.equals("-")) {
				erase(root, nextInt(), 30);
			} else {
				out.println(f(root, nextInt(), 30));
			}
		}
	}
	
	public int f(Node x, int value, int i) {
		if (i == 0) {
			if ((value & (1 << i)) == 0) {
				return (x.right == null || x.right.cnt == 0)
						? 0
						: 1;				
			} else {
				return (x.left == null || x.left.cnt == 0)
						? 0
						: 1;
			}
		} else {
			if ((value & (1 << i)) == 0) {
				return (x.right == null || x.right.cnt == 0)
						? f(x.left, value, i - 1)
						: f(x.right, value, i - 1) + (1 << i);				
			} else {
				return (x.left == null || x.left.cnt == 0)
						? f(x.right, value, i - 1)
						: f(x.left, value, i - 1) + (1 << i);
			}
		}
	}
	
	public void erase(Node x, int value, int i) {
		if (i == -1) {
			return;
		}
		if ((value & (1 << i)) == 0) {
			--x.left.cnt;
			erase(x.left, value, i - 1);
		} else {
			--x.right.cnt;
			erase(x.right, value, i - 1);
		}
	}
	
	public void insert(Node x, int value, int i) {
		if (i == -1) {
			return;
		}
		if ((value & (1 << i)) == 0) {
			if (x.left == null) {
				x.left = new Node();
			}
			++x.left.cnt;
			insert(x.left, value, i - 1);
		} else {
			if (x.right == null) {
				x.right = new Node();
			}
			++x.right.cnt;
			insert(x.right, value, i - 1);
		}
	}
	
	public class Node {
		Node left;
		Node right;
		int cnt;
		
		Node() {
			left = null;
			right = null;
			cnt = 0;
		}
	}
	
	public int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public BigInteger nextBigInteger() throws IOException {
		return new BigInteger(next());
	}
	
	public String next() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}
	
	public String nextLine() throws IOException {
		tok = new StringTokenizer("");
		return in.readLine();
	}

	public boolean hasNext() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null) {
				return false;
			}
			tok = new StringTokenizer(s);
		}
		return true;
	}
	
	public static void main(String args[]) {
		new Thread(null, new Main(), "Main", 1 << 28).start();
	}
	
	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
			//in = new BufferedReader(new FileReader("input.in"));
			//out = new PrintWriter(new FileWriter("output.out"));
			Locale.setDefault(Locale.US);
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			java.lang.System.exit(1);
		}
	}
}