#include <bits/stdc++.h>
using namespace std;
struct node {
  string C;
  char key;
  int val;
  node *left, *right, *mid;
  node() {
    val = 0;
    mid = NULL;
    left = NULL;
    right = NULL;
  }
};
class trie {
  node *root;
  void printhelper(node *temp) {
    if (temp == NULL) return;
    printhelper(temp->left);
    printhelper(temp->mid);
    printhelper(temp->right);
    if ((temp->C).size() != 0) cout << temp->C << "\n";
  }

 public:
  trie() { root = NULL; }
  void Insert(string S) {
    if (root == NULL) {
      root = new node;
      root->key = S[0];
    }
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      while (temp->key != S[i]) {
        if (temp->key > S[i]) {
          if (temp->left != NULL)
            temp = temp->left;
          else {
            temp->left = new node;
            temp = temp->left;
            temp->key = S[i];
          }
        } else {
          if (temp->right != NULL)
            temp = temp->right;
          else {
            temp->right = new node;
            temp = temp->right;
            temp->key = S[i];
          }
        }
      }
      temp->val++;
      if (i + 1 < S.size() && temp->mid != NULL)
        temp = temp->mid;
      else {
        ++i;
        for (; i < S.size(); ++i) {
          temp->mid = new node;
          temp = temp->mid;
          temp->key = S[i];
          temp->val++;
        }
      }
    }
    temp->C = S;
  }
  void Delete(string S) {
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      if (S[i] == temp->key) {
        temp->val--;
        temp = temp->mid;
      } else {
        if (temp->left != NULL)
          temp = temp->left;
        else
          temp = temp->right;
        temp->val--;
        temp = temp->mid;
      }
    }
  }
  string Search(string S) {
    string A;
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      if (temp->key == S[i] && temp->val != 0)
        A.push_back(S[i]);
      else if (temp->val == 0) {
        if (temp->left != NULL)
          temp = temp->left;
        else
          temp = temp->right;
        A.push_back(temp->key);
      } else {
        if (temp->key == '0') {
          if (temp->right != NULL && temp->right->val != 0) {
            temp = temp->right;
            A.push_back(S[i]);
          } else
            A.push_back('0');
        } else {
          if (temp->left != NULL && temp->left->val != 0) {
            temp = temp->left;
            A.push_back(S[i]);
          } else
            A.push_back('1');
        }
      }
      temp = temp->mid;
    }
    return A;
  }
  void print() { printhelper(root); }
} T;
void initial() {
  string A;
  for (int i = 0; i < 30; ++i) A.push_back('0');
  T.Insert(A);
}
int main() {
  initial();
  int q;
  cin >> q;
  while (q--) {
    int x;
    char ch;
    cin >> ch >> x;
    if (ch == '+') {
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('1');
        else
          S.push_back('0');
      }
      T.Insert(S);
    } else if (ch == '-') {
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('1');
        else
          S.push_back('0');
      }
      T.Delete(S);
    } else {
      int temp = 0;
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('0');
        else
          S.push_back('1');
      }
      S = T.Search(S);
      for (int i = 0; i < S.size(); ++i) {
        if (S[i] == '1') temp += (1 << (29 - i));
      }
      temp = (temp ^ x);
      cout << temp << "\n";
    }
  }
  return 0;
}

### Prompt

Please formulate a cpp solution to 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>
using namespace std;
struct node {
  string C;
  char key;
  int val;
  node *left, *right, *mid;
  node() {
    val = 0;
    mid = NULL;
    left = NULL;
    right = NULL;
  }
};
class trie {
  node *root;
  void printhelper(node *temp) {
    if (temp == NULL) return;
    printhelper(temp->left);
    printhelper(temp->mid);
    printhelper(temp->right);
    if ((temp->C).size() != 0) cout << temp->C << "\n";
  }

 public:
  trie() { root = NULL; }
  void Insert(string S) {
    if (root == NULL) {
      root = new node;
      root->key = S[0];
    }
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      while (temp->key != S[i]) {
        if (temp->key > S[i]) {
          if (temp->left != NULL)
            temp = temp->left;
          else {
            temp->left = new node;
            temp = temp->left;
            temp->key = S[i];
          }
        } else {
          if (temp->right != NULL)
            temp = temp->right;
          else {
            temp->right = new node;
            temp = temp->right;
            temp->key = S[i];
          }
        }
      }
      temp->val++;
      if (i + 1 < S.size() && temp->mid != NULL)
        temp = temp->mid;
      else {
        ++i;
        for (; i < S.size(); ++i) {
          temp->mid = new node;
          temp = temp->mid;
          temp->key = S[i];
          temp->val++;
        }
      }
    }
    temp->C = S;
  }
  void Delete(string S) {
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      if (S[i] == temp->key) {
        temp->val--;
        temp = temp->mid;
      } else {
        if (temp->left != NULL)
          temp = temp->left;
        else
          temp = temp->right;
        temp->val--;
        temp = temp->mid;
      }
    }
  }
  string Search(string S) {
    string A;
    node *temp = root;
    for (int i = 0; i < S.size(); ++i) {
      if (temp->key == S[i] && temp->val != 0)
        A.push_back(S[i]);
      else if (temp->val == 0) {
        if (temp->left != NULL)
          temp = temp->left;
        else
          temp = temp->right;
        A.push_back(temp->key);
      } else {
        if (temp->key == '0') {
          if (temp->right != NULL && temp->right->val != 0) {
            temp = temp->right;
            A.push_back(S[i]);
          } else
            A.push_back('0');
        } else {
          if (temp->left != NULL && temp->left->val != 0) {
            temp = temp->left;
            A.push_back(S[i]);
          } else
            A.push_back('1');
        }
      }
      temp = temp->mid;
    }
    return A;
  }
  void print() { printhelper(root); }
} T;
void initial() {
  string A;
  for (int i = 0; i < 30; ++i) A.push_back('0');
  T.Insert(A);
}
int main() {
  initial();
  int q;
  cin >> q;
  while (q--) {
    int x;
    char ch;
    cin >> ch >> x;
    if (ch == '+') {
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('1');
        else
          S.push_back('0');
      }
      T.Insert(S);
    } else if (ch == '-') {
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('1');
        else
          S.push_back('0');
      }
      T.Delete(S);
    } else {
      int temp = 0;
      string S;
      for (int i = 29; i >= 0; --i) {
        if (x & (1 << i))
          S.push_back('0');
        else
          S.push_back('1');
      }
      S = T.Search(S);
      for (int i = 0; i < S.size(); ++i) {
        if (S[i] == '1') temp += (1 << (29 - i));
      }
      temp = (temp ^ x);
      cout << temp << "\n";
    }
  }
  return 0;
}

```