#include <bits/stdc++.h>
using namespace std;
inline int nxt() {
  int a;
  scanf("%d", &a);
  return a;
}
inline long long int NXT() {
  long long int a;
  scanf("%lld", &a);
  return a;
}
struct node {
  int value;
  int child[3];
  void clear() {
    memset(child, 0, sizeof(child));
    value = 0;
  }
} trie[500000 + 10];
int indx;
int mark[100000 + 10];
void initialize() {
  trie[0].clear();
  indx = 1;
  memset(mark, 0, sizeof(mark));
}
void insertTrie(string s, int a) {
  int len = s.size();
  int cur = 0;
  for (int i = 0; i < len; i++) {
    int val = (s[i] - '0') % 2;
    if (trie[cur].child[val] == 0) {
      trie[indx].clear();
      trie[cur].child[val] = indx;
      indx++;
    }
    cur = trie[cur].child[val];
    if (a == 1)
      trie[cur].value++;
    else {
      trie[cur].value--;
      if (trie[cur].value < 0) trie[cur].value = 0;
    }
  }
  return;
}
int search(string s) {
  int res = (int)10e7;
  int len = s.length();
  int cur = 0;
  for (int i = 0; i < len; i++) {
    int val = (s[i] - '0') % 2;
    if (trie[cur].child[val] == 0) return 0;
    cur = trie[cur].child[val];
    res = min(res, trie[cur].value);
  }
  return res;
}
string fill(string s) {
  reverse(s.begin(), s.end());
  while (s.size() != 19) s.push_back('0');
  reverse(s.begin(), s.end());
  return s;
}
int main() {
  initialize();
  int n = nxt();
  for (int i = 0; i < n; i++) {
    string s, t;
    cin >> s >> t;
    t = fill(t);
    if (s == "+")
      insertTrie(t, 1);
    else if (s == "-")
      insertTrie(t, 2);
    else
      printf("%d\n", search(t));
  }
}
