#include <bits/stdc++.h>
#pragma comment(linker, "/stack:336777216")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
ll const mod = 1000000007;
template <int span, int scale>
class Trie {
 public:
  template <int node_span>
  class Node {
   public:
    array<Node<node_span>*, node_span> child = {nullptr};
    int count = 0, end = 0;
    char data;
    Node(char c) : data(c){};
  };
  Node<span>* root = new Node<span>(0);
  void insert(string const& s) {
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      if (curr->child[x] == nullptr) curr->child[x] = new Node<span>(c);
      curr = curr->child[x];
      curr->count++;
    }
    curr->end = 1;
  }
  void erase(string const& s) {
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      curr = curr->child[x];
      curr->count--;
    }
  }
  ull getbest(string const& s) {
    bitset<32> best;
    best.reset();
    int count = 31;
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      if (curr->child[x] == nullptr || curr->child[x]->count == 0)
        curr = curr->child[1 - x];
      else
        curr = curr->child[x];
      best[count] = curr->data - scale;
      count--;
    }
    return best.to_ullong();
  }
};
int main() {
  ios_base::sync_with_stdio(false), cin.tie(nullptr);
  Trie<2, '0'> trie;
  trie.insert("00000000000000000000000000000000");
  int q;
  cin >> q;
  while (q--) {
    char c;
    ull x;
    cin >> c >> x;
    bitset<32> bits(x);
    if (c == '+')
      trie.insert(bits.to_string());
    else if (c == '-')
      trie.erase(bits.to_string());
    else {
      cout << (trie.getbest(bits.to_string('1', '0')) ^ x) << '\n';
    }
  }
  return 0;
}

### Prompt

In cpp, your task is to solve the following problem:

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>.

### Response

```cpp
#include <bits/stdc++.h>
#pragma comment(linker, "/stack:336777216")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
ll const mod = 1000000007;
template <int span, int scale>
class Trie {
 public:
  template <int node_span>
  class Node {
   public:
    array<Node<node_span>*, node_span> child = {nullptr};
    int count = 0, end = 0;
    char data;
    Node(char c) : data(c){};
  };
  Node<span>* root = new Node<span>(0);
  void insert(string const& s) {
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      if (curr->child[x] == nullptr) curr->child[x] = new Node<span>(c);
      curr = curr->child[x];
      curr->count++;
    }
    curr->end = 1;
  }
  void erase(string const& s) {
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      curr = curr->child[x];
      curr->count--;
    }
  }
  ull getbest(string const& s) {
    bitset<32> best;
    best.reset();
    int count = 31;
    Node<span>* curr = root;
    for (auto& c : s) {
      int x = c - scale;
      if (curr->child[x] == nullptr || curr->child[x]->count == 0)
        curr = curr->child[1 - x];
      else
        curr = curr->child[x];
      best[count] = curr->data - scale;
      count--;
    }
    return best.to_ullong();
  }
};
int main() {
  ios_base::sync_with_stdio(false), cin.tie(nullptr);
  Trie<2, '0'> trie;
  trie.insert("00000000000000000000000000000000");
  int q;
  cin >> q;
  while (q--) {
    char c;
    ull x;
    cin >> c >> x;
    bitset<32> bits(x);
    if (c == '+')
      trie.insert(bits.to_string());
    else if (c == '-')
      trie.erase(bits.to_string());
    else {
      cout << (trie.getbest(bits.to_string('1', '0')) ^ x) << '\n';
    }
  }
  return 0;
}

```