#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, z, k, w, cnt, fuck;
char s[100];
string s2;
unordered_map<string, int> M;
int A[100005], B[100005], C[100005], D[100005];
int T[12000005], L[12000005], R[12000005];
int prio[12000005], L2[12000005], R2[12000005], cnt2;
int Root[100005], prio_root[100005], r, tmp, p;
void update(int x, int l, int r, int pos, int val, int pre) {
  if (l == r)
    T[x] = T[pre] + val;
  else {
    int mid = (l + r) / 2;
    if (pos <= mid) {
      L[x] = ++cnt, R[x] = R[pre];
      update(L[x], l, mid, pos, val, L[pre]);
    } else {
      R[x] = ++cnt, L[x] = L[pre];
      update(R[x], mid + 1, r, pos, val, R[pre]);
    }
    T[x] = T[L[x]] + T[R[x]];
  }
}
void update2(int x, int l, int r, int pos, int val, int pre) {
  if (l == r)
    prio[x] = val;
  else {
    int mid = (l + r) / 2;
    if (pos <= mid) {
      L2[x] = ++cnt2, R2[x] = R2[pre];
      update2(L2[x], l, mid, pos, val, L2[pre]);
    } else {
      R2[x] = ++cnt2, L2[x] = L2[pre];
      update2(R2[x], mid + 1, r, pos, val, R2[pre]);
    }
  }
}
int query(int x, int l, int r, int tr) {
  if (r <= tr)
    return T[x];
  else if (l > tr)
    return 0;
  else {
    int mid = (l + r) / 2;
    int a, b;
    if (L[x] == 0)
      a = 0;
    else
      a = query(L[x], l, mid, tr);
    if (R[x] == 0)
      b = 0;
    else
      b = query(R[x], mid + 1, r, tr);
    return a + b;
  }
}
int query2(int x, int l, int r, int pos) {
  if (l == r)
    return prio[x];
  else {
    int mid = (l + r) / 2;
    if (pos <= mid) {
      if (L2[x] == 0)
        return 0;
      else
        return query2(L2[x], l, mid, pos);
    } else {
      if (R2[x] == 0)
        return 0;
      else
        return query2(R2[x], mid + 1, r, pos);
    }
  }
}
int main() {
  int Q;
  scanf("%d", &Q);
  n = 1000000000;
  cnt = cnt2 = 0;
  Root[0] = 0;
  prio_root[0] = 0;
  for (int i = (1); i <= (Q); i++) {
    scanf("%s", s);
    if (s[0] == 's')
      A[i] = 1;
    else if (s[0] == 'q')
      A[i] = 2;
    else if (s[0] == 'r')
      A[i] = 3;
    else
      A[i] = 4;
    if (A[i] <= 3) {
      scanf("%s", s);
      s2 = string(s);
      if (M.find(s2) == M.end()) M.insert(make_pair(s2, ++fuck));
      B[i] = M[s2];
    }
    if (A[i] == 1)
      scanf("%d", &C[i]);
    else if (A[i] == 4)
      scanf("%d", &B[i]);
    r = Root[i - 1];
    if (A[i] == 1) {
      p = query2(prio_root[i - 1], 1, n, B[i]);
      if (p != 0) {
        tmp = ++cnt;
        update(tmp, 1, n, p, -1, r);
        p = C[i];
        Root[i] = ++cnt;
        update(cnt, 1, n, p, 1, tmp);
      } else {
        Root[i] = ++cnt;
        update(cnt, 1, n, C[i], 1, r);
      }
      prio_root[i] = ++cnt2;
      update2(cnt2, 1, n, B[i], C[i], prio_root[i - 1]);
    } else if (A[i] == 2) {
      Root[i] = Root[i - 1];
      prio_root[i] = prio_root[i - 1];
      p = query2(prio_root[i - 1], 1, n, B[i]);
      if (p == 0)
        printf("-1\n");
      else
        printf("%d\n", query(r, 1, n, p - 1));
      fflush(stdout);
    } else if (A[i] == 3) {
      p = query2(prio_root[i - 1], 1, n, B[i]);
      if (p == 0) {
        Root[i] = Root[i - 1];
        prio_root[i] = prio_root[i - 1];
        continue;
      }
      Root[i] = ++cnt;
      update(cnt, 1, n, p, -1, r);
      prio_root[i] = ++cnt2;
      update2(cnt2, 1, n, B[i], 0, prio_root[i - 1]);
    } else
      Root[i] = Root[i - 1 - B[i]], prio_root[i] = prio_root[i - 1 - B[i]];
  }
  return 0;
}
