#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
inline void chkmin(T1 &x, T2 y) {
  if (y < x) x = y;
};
template <typename T1, typename T2>
inline void chkmax(T1 &x, T2 y) {
  if (y > x) x = y;
};
string rev(int x) {
  string res = "";
  for (int i = 29; i >= 0; --i) {
    if (x & (1 << i))
      res.push_back('1');
    else
      res.push_back('0');
  }
  return res;
}
struct numtrie {
  numtrie *l, *r;
  int sz;
  int term;
  numtrie() {
    l = r = nullptr;
    sz = 0;
    term = 0;
  }
};
int numtrie_sz(numtrie *t) {
  if (t == nullptr) return 0;
  return t->sz;
}
void numtrie_update(numtrie *&t) {
  if (t == nullptr) return;
  t->sz = t->term;
  if (t->l != nullptr) {
    t->sz += t->l->sz;
  }
  if (t->r != nullptr) {
    t->sz += t->r->sz;
  }
}
numtrie *numtrie_clone(numtrie *t) {
  numtrie *nt = new numtrie();
  nt->l = t->l;
  nt->r = t->r;
  nt->sz = t->sz;
  nt->term = t->term;
  return nt;
}
numtrie *numtrie_add(numtrie *t, string &second, int i, int d) {
  numtrie *nt = numtrie_clone(t);
  if (i == (int)second.size()) {
    nt->sz += d;
    nt->term += d;
  } else if (second[i] == '1') {
    if (nt->r == nullptr) {
      nt->r = new numtrie();
    }
    nt->r = numtrie_add(nt->r, second, i + 1, d);
  } else {
    if (nt->l == nullptr) {
      nt->l = new numtrie();
    }
    nt->l = numtrie_add(nt->l, second, i + 1, d);
  }
  numtrie_update(nt);
  return nt;
}
int numtrie_get(numtrie *t, string &second, int i) {
  if (i == (int)second.size()) return 0;
  if (second[i] == '1') {
    return numtrie_sz(t->l) + numtrie_get(t->r, second, i + 1);
  } else {
    return numtrie_get(t->l, second, i + 1);
  }
}
struct trie {
  vector<trie *> go;
  int x;
  trie() {
    x = -1;
    go.assign(26, nullptr);
  }
};
trie *trie_clone(trie *t) {
  trie *nt = new trie();
  nt->x = t->x;
  for (int c = 0; c < 26; ++c) nt->go[c] = t->go[c];
  return nt;
}
trie *trie_set(trie *t, string &second, int i, int x) {
  if (i == (int)second.size()) {
    trie *nt = trie_clone(t);
    nt->x = x;
    return nt;
  }
  trie *nt = trie_clone(t);
  int c = second[i] - 'a';
  if (nt->go[c] == nullptr) {
    nt->go[c] = new trie();
  }
  nt->go[c] = trie_set(nt->go[c], second, i + 1, x);
  return nt;
}
int trie_get(trie *t, string &second, int i) {
  if (t == nullptr) return -1;
  if (i == (int)second.size()) return t->x;
  int c = second[i] - 'a';
  return trie_get(t->go[c], second, i + 1);
}
numtrie *ntr[100005];
trie *tr[100005];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL), cout.tie(NULL);
  ntr[0] = new numtrie();
  tr[0] = new trie();
  int Q;
  cin >> Q;
  for (int i = 1; i <= Q; ++i) {
    ntr[i] = ntr[i - 1];
    tr[i] = tr[i - 1];
    string cmd;
    cin >> cmd;
    if (cmd == "set") {
      string a;
      cin >> a;
      int x;
      cin >> x;
      int res = trie_get(tr[i], a, 0);
      if (res != -1) {
        string kek = rev(res);
        ntr[i] = numtrie_add(ntr[i], kek, 0, -1);
      }
      tr[i] = trie_set(tr[i], a, 0, x);
      string kek = rev(x);
      ntr[i] = numtrie_add(ntr[i], kek, 0, 1);
    } else if (cmd == "remove") {
      string a;
      cin >> a;
      int res = trie_get(tr[i], a, 0);
      if (res != -1) {
        tr[i] = trie_set(tr[i], a, 0, -1);
        string kek = rev(res);
        ntr[i] = numtrie_add(ntr[i], kek, 0, -1);
      }
    } else if (cmd == "query") {
      string a;
      cin >> a;
      int res = trie_get(tr[i], a, 0);
      if (res == -1) {
        cout << -1 << endl;
      } else {
        string kek = rev(res);
        cout << numtrie_get(ntr[i], kek, 0) << endl;
      }
    } else {
      int x;
      cin >> x;
      tr[i] = tr[i - x - 1];
      ntr[i] = ntr[i - x - 1];
    }
  }
  return 0;
}
