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>.
//package com.codeforces.competitions.year2016.julytoseptember.round367div2;

import java.io.*;
import java.util.*;

public final class TaskD
{
	public static void main(String[] args)
	{
		InputReader in = new InputReader(System.in);
		OutputWriter out = new OutputWriter(System.out);

		Solver solver = new Solver(in, out);
		try
		{
			solver.solve();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}

		out.flush();

		in.close();
		out.close();
	}

	static class Solver
	{
		int q;
		Node root;
		InputReader in;
		OutputWriter out;

		void solve() throws IOException
		{
/*			System.out.println("9 : " + Integer.toBinaryString(9));
			System.out.println("-9 : " + Integer.toBinaryString(-9));
			System.out.println("~9 : " + Integer.toBinaryString(~9));
			System.out.println(~9);
			System.out.println("-10 : " + Integer.toBinaryString(-10));
			System.out.println("-9 : " + Integer.toBinaryString(-9));
			System.out.println("-8 : " + Integer.toBinaryString(-8));
			System.out.println("-7 : " + Integer.toBinaryString(-7));
			System.out.println("-6 : " + Integer.toBinaryString(-6));
			System.out.println("-5 : " + Integer.toBinaryString(-5));
			System.out.println("-4 : " + Integer.toBinaryString(-4));
			System.out.println("-3 : " + Integer.toBinaryString(-3));
			System.out.println("-2 : " + Integer.toBinaryString(-2));
			System.out.println("-1 : " + Integer.toBinaryString(-1));

			System.out.println(~-10);*/

			root = new Node();

			String zeroes = "00000000000000000000000000000000";
			root = insert(root, zeroes, zeroes.length(), 0);

			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
			q = Integer.parseInt(reader.readLine());

			while (q-- > 0)
			{
				String[] tokens = reader.readLine().split(" ");
				int x = Integer.parseInt(tokens[1]);
				String binary = Integer.toBinaryString(x);
				int len = binary.length();

				if (tokens[0].charAt(0) == '+')
					root = insert(root, zeroes.substring(0, 32 - len) + binary, 32, 0);
				else if (tokens[0].charAt(0) == '-')
					remove(root, zeroes.substring(0, 32 - len) + binary, 32, 0);
				else
					out.println(maxXor(root, zeroes.substring(0, 32 - len) + binary, 32, 0));
			}
		}

		Node insert(Node node, String word, int length, int index)
		{
			int pos = word.charAt(index) - '0';
			Node temp = node.next[pos];

			if (temp == null)
				temp = new Node();

			if (index == length - 1)
				temp.isWord++;
			else
				temp = insert(temp, word, length, index + 1);

			temp.exists++;
			node.next[pos] = temp;

			return node;
		}

		long maxXor(Node node, String word, int length, int index)
		{
			int pos = word.charAt(index) - '0';
			int req = (pos + 1) % 2;
			Node temp = node.next[pos];
			Node reqTemp = node.next[req];

			if (index == length - 1)
			{
				if (reqTemp != null && reqTemp.isWord > 0)
					return (1 << (length - 1 - index));

				return 0;
			}

			if (reqTemp != null)
			{
				if (reqTemp.exists > 0)
					return (1 << (length - 1 - index)) + maxXor(reqTemp, word, length, index + 1);
				else
				{
					if (temp != null)
						return Math.max(maxXor(temp, word, length, index + 1), maxXor(reqTemp, word, length, index +
								1));

					return maxXor(reqTemp, word, length, index + 1);
				}
			}

			if (temp != null)
				return maxXor(temp, word, length, index + 1);

			return 0;
		}

		void remove(Node node, String word, int length, int index)
		{
			int pos = word.charAt(index) - '0';
			Node temp = node.next[pos];

			temp.exists--;

			if (index == length - 1)
			{
				if (temp.isWord > 0)
					temp.isWord--;

				return;
			}

			remove(temp, word, length, index + 1);
		}

		boolean contains(Node node, String word, int length, int index)
		{
			int pos = word.charAt(index) - '0';
			Node temp = node.next[pos];

			if (temp == null)
				return false;

			if (index == length - 1)
				return temp.isWord > 0;

			return contains(temp, word, length, index + 1);
		}

		class Node
		{
			int isWord, exists;
			Node[] next;

			public Node()
			{
				next = new Node[2];
			}

		}

		public Solver(InputReader in, OutputWriter out)
		{
			this.in = in;
			this.out = out;
		}

	}

	static class InputReader
	{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int read()
		{
			if (numChars == -1)
				throw new InputMismatchException();

			if (curChar >= numChars)
			{
				curChar = 0;
				try
				{
					numChars = stream.read(buf);
				}
				catch (IOException e)
				{
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}

			return buf[curChar++];
		}

		public int nextInt()
		{
			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-')
			{
				sgn = -1;
				c = read();
			}

			int res = 0;

			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();

				res *= 10;
				res += c & 15;

				c = read();
			} while (!isSpaceChar(c));

			return res * sgn;
		}

		public int[] nextIntArray(int arraySize)
		{
			int array[] = new int[arraySize];

			for (int i = 0; i < arraySize; i++)
				array[i] = nextInt();

			return array;
		}

		public long nextLong()
		{
			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sign = 1;

			if (c == '-')
			{
				sign = -1;

				c = read();
			}

			long result = 0;

			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();

				result *= 10;
				result += c & 15;

				c = read();
			} while (!isSpaceChar(c));

			return result * sign;
		}

		public long[] nextLongArray(int arraySize)
		{
			long array[] = new long[arraySize];

			for (int i = 0; i < arraySize; i++)
				array[i] = nextLong();

			return array;
		}

		public float nextFloat() // problematic
		{
			float result, div;
			byte c;

			result = 0;
			div = 1;
			c = (byte) read();

			while (c <= ' ')
				c = (byte) read();

			boolean isNegative = (c == '-');

			if (isNegative)
				c = (byte) read();

			do
			{
				result = result * 10 + c - '0';
			} while ((c = (byte) read()) >= '0' && c <= '9');

			if (c == '.')
				while ((c = (byte) read()) >= '0' && c <= '9')
					result += (c - '0') / (div *= 10);

			if (isNegative)
				return -result;

			return result;
		}

		public double nextDouble() // not completely accurate
		{
			double ret = 0, div = 1;
			byte c = (byte) read();

			while (c <= ' ')
				c = (byte) read();

			boolean neg = (c == '-');

			if (neg)
				c = (byte) read();

			do
			{
				ret = ret * 10 + c - '0';
			} while ((c = (byte) read()) >= '0' && c <= '9');

			if (c == '.')
				while ((c = (byte) read()) >= '0' && c <= '9')
					ret += (c - '0') / (div *= 10);

			if (neg)
				return -ret;

			return ret;
		}

		public String next()
		{
			int c = read();

			while (isSpaceChar(c))
				c = read();

			StringBuilder res = new StringBuilder();

			do
			{
				res.appendCodePoint(c);

				c = read();
			} while (!isSpaceChar(c));

			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public String nextLine()
		{
			int c = read();

			StringBuilder result = new StringBuilder();

			do
			{
				result.appendCodePoint(c);

				c = read();
			} while (!isNewLine(c));

			return result.toString();
		}

		public boolean isNewLine(int c)
		{
			return c == '\n';
		}

		public void close()
		{
			try
			{
				stream.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}

	}

	static class OutputWriter
	{
		private PrintWriter writer;

		public OutputWriter(OutputStream stream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(stream)));
		}

		public OutputWriter(Writer writer)
		{
			this.writer = new PrintWriter(writer);
		}

		public void println(int x)
		{
			writer.println(x);
		}

		public void print(int x)
		{
			writer.print(x);
		}

		public void println(char x)
		{
			writer.println(x);
		}

		public void print(char x)
		{
			writer.print(x);
		}

		public void println(int array[], int size)
		{
			for (int i = 0; i < size; i++)
				println(array[i]);
		}

		public void print(int array[], int size)
		{
			for (int i = 0; i < size; i++)
				print(array[i] + " ");
		}

		public void println(long x)
		{
			writer.println(x);
		}

		public void print(long x)
		{
			writer.print(x);
		}

		public void println(long array[], int size)
		{
			for (int i = 0; i < size; i++)
				println(array[i]);
		}

		public void print(long array[], int size)
		{
			for (int i = 0; i < size; i++)
				print(array[i]);
		}

		public void println(float num)
		{
			writer.println(num);
		}

		public void print(float num)
		{
			writer.print(num);
		}

		public void println(double num)
		{
			writer.println(num);
		}

		public void print(double num)
		{
			writer.print(num);
		}

		public void println(String s)
		{
			writer.println(s);
		}

		public void print(String s)
		{
			writer.print(s);
		}

		public void println()
		{
			writer.println();
		}

		public void printSpace()
		{
			writer.print(" ");
		}

		public void printf(String format, Object args)
		{
			writer.printf(format, args);
		}

		public void flush()
		{
			writer.flush();
		}

		public void close()
		{
			writer.close();
		}

	}

	static class CMath
	{
		static long power(long number, long power)
		{
			if (number == 1 || number == 0 || power == 0)
				return 1;

			if (power == 1)
				return number;

			if (power % 2 == 0)
				return power(number * number, power / 2);
			else
				return power(number * number, power / 2) * number;
		}

		static long modPower(long number, long power, long mod)
		{
			if (number == 1 || number == 0 || power == 0)
				return 1;

			number = mod(number, mod);

			if (power == 1)
				return number;

			long square = mod(number * number, mod);

			if (power % 2 == 0)
				return modPower(square, power / 2, mod);
			else
				return mod(modPower(square, power / 2, mod) * number, mod);
		}

		static long moduloInverse(long number, long mod)
		{
			return modPower(number, mod - 2, mod);
		}

		static long mod(long number, long mod)
		{
			return number - (number / mod) * mod;
		}

		static int gcd(int a, int b)
		{
			if (b == 0)
				return a;
			else
				return gcd(b, a % b);
		}

	}

}

/*

-9 : 11111111111111111111111111110111

12
? 1
+ 1
+ 7
? 2
+ 3
? 1
? 6
+ 4
+ 6
+ 8
- 8
? 3

10
? 1
+ 1
+ 7
? 2
+ 3
? 1
? 6
+ 4
+ 6
? 3

*/
