#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:536870912")
#pragma warning(disable : 4996)
using namespace std;
struct Node {
  long long int p, sz = 0;
  pair<int, int> val = {0, 0}, mx = {0, 0};
  Node *l = nullptr, *r = nullptr;
  Node(Node *l, Node *r, pair<int, int> val, long long int p)
      : l(l), r(r), val(val), p(p) {
    sz = (l == nullptr ? 0 : l->sz) + (r == nullptr ? 0 : r->sz) + 1;
    mx = max(max((l == nullptr ? make_pair(0, 0) : l->mx),
                 (r == nullptr ? make_pair(0, 0) : r->mx)),
             val);
  }
};
int lowB(Node *a, pair<int, int> k) {
  if (a == nullptr) return 0;
  if ((a->l == nullptr ? make_pair(0, 0) : a->l->mx) >= k) return lowB(a->l, k);
  if (a->val >= k) return (a->l == nullptr ? 0 : a->l->sz);
  return lowB(a->r, k) + (a->l == nullptr ? 0 : a->l->sz) + 1;
}
pair<Node *, Node *> split(Node *a, int k) {
  if (k == 0) return {nullptr, a};
  if ((a->l == nullptr ? 0 : a->l->sz) >= k) {
    auto g = split(a->l, k);
    return {g.first, new Node(g.second, a->r, a->val, a->p)};
  }
  auto g = split(a->r, k - (a->l == nullptr ? 0 : a->l->sz) - 1);
  return {new Node(a->l, g.first, a->val, a->p), g.second};
}
Node *merge(Node *a, Node *b) {
  if (a == nullptr) return b;
  if (b == nullptr) return a;
  if (a->p < b->p) {
    Node *q = merge(a->r, b);
    return new Node(a->l, q, a->val, a->p);
  }
  Node *q = merge(a, b->l);
  return new Node(q, b->r, b->val, b->p);
}
struct TNode {
  int val = 0;
  TNode *l = nullptr, *r = nullptr;
  TNode(TNode *l, TNode *r, int val) : l(l), r(r), val(val) {}
  void build(int L, int R) {
    if (L != R) {
      int m = (L + R) >> 1;
      l = new TNode(nullptr, nullptr, 0);
      r = new TNode(nullptr, nullptr, 0);
      l->build(L, m);
      r->build(m + 1, R);
    }
  }
  int que(int x, int L, int R) {
    if (L == R) return val;
    int m = (L + R) >> 1;
    if (x <= m) return l->que(x, L, m);
    return r->que(x, m + 1, R);
  }
  TNode *upd(int x, int nv, int L, int R) {
    if (L == R) return new TNode(nullptr, nullptr, nv);
    int m = (L + R) >> 1;
    if (x <= m) return new TNode(l->upd(x, nv, L, m), r, 0);
    return new TNode(l, r->upd(x, nv, m + 1, R), 0);
  }
};
const int N = 20, Q = 1e5 + 100;
char s[N], cm[N];
map<string, int> mp;
Node *rt[Q];
TNode *vv[Q];
Node *del(Node *a, pair<int, int> val) {
  int k = lowB(a, val);
  auto g = split(a, k);
  a = g.first;
  g = split(g.second, 1);
  a = merge(a, g.second);
  return a;
}
Node *ins(Node *r, Node *a) {
  int k = lowB(r, a->val);
  auto g = split(r, k);
  r = merge(merge(g.first, a), g.second);
  return r;
}
int main() {
  int q;
  scanf("%d", &q);
  vv[0] = new TNode(nullptr, nullptr, 0);
  vv[0]->build(0, q);
  for (int i = 1; i <= q; i++) {
    rt[i] = rt[i - 1];
    vv[i] = vv[i - 1];
    scanf(" %s", cm);
    if (cm[0] == 'u') {
      int x;
      scanf("%d", &x);
      rt[i] = rt[i - x - 1];
      vv[i] = vv[i - x - 1];
    } else {
      string a;
      scanf(" %s", s);
      a = (string)s;
      int w;
      if (!mp.count(a))
        w = mp[a] = mp.size() + 1;
      else
        w = mp[a];
      int cv = vv[i]->que(w, 0, q);
      if (cm[0] == 's') {
        int x;
        scanf("%d", &x);
        if (cv) {
          rt[i] = del(rt[i], {cv, w});
        }
        vv[i] = vv[i]->upd(w, x, 0, q);
        rt[i] = ins(rt[i], new Node(nullptr, nullptr, {x, w},
                                    rand() * (long long int)rand()));
      } else if (cm[0] == 'r') {
        if (cv) {
          rt[i] = del(rt[i], {cv, w});
          vv[i] = vv[i]->upd(w, 0, 0, q);
        }
      } else {
        if (!cv)
          printf("-1\n");
        else
          printf("%d\n", lowB(rt[i], {cv, -1}));
        fflush(stdout);
      }
    }
  }
  return 0;
}
