#include <bits/stdc++.h>
#pragma GCC optimize("-O3")
using namespace std;
void _main();
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  _main();
}
const int inf = INT_MAX / 2;
const long long infl = 1LL << 60;
template <class T>
bool chmax(T& a, const T& b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T& a, const T& b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
struct PersistentStringTrie {
  struct Node {
    int cnt, dep;
    Node* c[26];
    Node() {
      cnt = dep = 0;
      for (int i = 0; i < 26; i++) c[i] = 0;
    }
  };
  Node* root;
  PersistentStringTrie() { root = new Node(); }
  Node* add(Node* n, string x, int d = 1) {
    update(n, x, d);
    return n;
  }
  Node* duplicate(Node* n) {
    Node* res = new Node();
    if (!n) return res;
    res->cnt = n->cnt;
    res->dep = n->dep;
    for (int i = 0; i < 26; i++) res->c[i] = n->c[i];
    return res;
  }
  void update(Node*& x, string& a, int d, int b = 0) {
    x = duplicate(x);
    x->dep = b;
    if (b == a.length()) {
      x->cnt += d;
      return;
    }
    update(x->c[a[b] - 'a'], a, d, b + 1);
  }
  void dump() { dump(root); }
  void dump(Node*& x) {
    printf("%d [cnt:%d,dep:%d]", x, x->cnt, x->dep);
    for (int i = 0; i < 26; i++) {
      if (x->c[i]) printf(" (%c -> %d)", char('a' + i), x->c[i]);
    }
    printf("\n");
    for (int i = 0; i < 26; i++)
      if (x->c[i]) dump(x->c[i]);
  }
  int getValues(Node* n, string& s) {
    if (!n) return -1;
    if (n->dep == s.length()) return n->cnt;
    return getValues(n->c[s[n->dep] - 'a'], s);
  }
};
struct PersistentSegmentTree {
  int comp(int a, int b) { return a + b; }
  struct S {
    int l, r;
    int x;
  } v[10010101];
  int cnt = 1, n = -1;
  void init(int _n) {
    n = _n;
    for (int i = 0; i < 10010101; i++) v[i].l = v[i].r = 0, v[i].x = 0;
  }
  void add(int& root, int l, int r, int i, int val) {
    v[cnt] = v[root];
    root = cnt++;
    if (l + 1 == r) {
      v[root].x += val;
      return;
    }
    int mi = (l + r) / 2;
    if (i < mi)
      add(v[root].l, l, mi, i, val);
    else
      add(v[root].r, mi, r, i, val);
    v[root].x = comp(v[v[root].l].x, v[v[root].r].x);
  }
  void add(int& root, int i, int val) {
    assert(0 < n);
    add(root, 0, n, i, val);
  }
  void update(int& root, int l, int r, int i, int val) {
    v[cnt] = v[root];
    root = cnt++;
    if (l + 1 == r) {
      v[root].x = val;
      return;
    }
    int mi = (l + r) / 2;
    if (i < mi)
      update(v[root].l, l, mi, i, val);
    else
      update(v[root].r, mi, r, i, val);
    v[root].x = comp(v[v[root].l].x, v[v[root].r].x);
  }
  void update(int& root, int i, int val) {
    assert(0 < n);
    update(root, 0, n, i, val);
  }
  int allget(int root) {
    assert(0 < n);
    return v[root].x;
  }
  int get(int root, int l, int r, int L, int R) {
    if (l >= r) return 0;
    if (l == L && r == R) return v[root].x;
    int mi = (L + R) / 2;
    int le = get(v[root].l, max(l, L), min(r, mi), L, mi);
    int ri = get(v[root].r, max(l, mi), min(r, R), mi, R);
    return comp(le, ri);
  }
  int get(int root, int l, int r) {
    assert(0 < n);
    return get(root, l, r, 0, n);
  }
};
PersistentStringTrie pstrie;
PersistentSegmentTree pstree;
int N;
PersistentStringTrie::Node* trie[101010];
int tree[101010];
void _main() {
  cin >> N;
  pstree.init(inf);
  trie[0] = pstrie.root;
  tree[0] = 0;
  int cur = 0;
  for (int t = 1; t < N + 1; t++) {
    string ty;
    cin >> ty;
    if (ty == "set") {
      string a;
      int x;
      cin >> a >> x;
      int xx = pstrie.getValues(trie[cur], a);
      tree[t] = tree[cur];
      if (0 < xx) {
        trie[t] = pstrie.add(trie[cur], a, -xx + x);
        pstree.add(tree[t], xx, -1);
        pstree.add(tree[t], x, 1);
      } else {
        trie[t] = pstrie.add(trie[cur], a, x);
        pstree.add(tree[t], x, 1);
      }
    } else if (ty == "remove") {
      string a;
      cin >> a;
      int xx = pstrie.getValues(trie[cur], a);
      tree[t] = tree[cur];
      if (xx <= 0) {
        trie[t] = pstrie.duplicate(trie[cur]);
      } else {
        trie[t] = pstrie.add(trie[cur], a, -xx);
        pstree.add(tree[t], xx, -1);
      }
    } else if (ty == "query") {
      string a;
      cin >> a;
      int xx = pstrie.getValues(trie[cur], a);
      trie[t] = pstrie.duplicate(trie[cur]);
      tree[t] = tree[cur];
      int ans = -1;
      if (0 < xx) ans = pstree.get(tree[t], 1, xx);
      printf("%d\n", ans);
      fflush(stdout);
    } else {
      int d;
      cin >> d;
      trie[t] = pstrie.duplicate(trie[t - 1 - d]);
      tree[t] = tree[t - 1 - d];
    }
    cur = t;
  }
}
