#include <bits/stdc++.h>
#pragma gcc optimize("Ofast,unroll-loops")
#pragma gcc options("sse,sse2,sse3,sse4,popcnt,tune=native")
using namespace std;
using ll = long long;
using ipair = pair<int, int>;
using llpair = pair<ll, ll>;
struct Node {
  Node *l = nullptr, *r = nullptr;
  ll val = 0;
  Node* gl() {
    if (l == nullptr) {
      return l = new Node();
    }
    return l;
  }
  Node* gr() {
    if (r == nullptr) {
      return r = new Node();
    }
    return r;
  }
  Node* set(long long id, long long lb, long long rb, ll d) {
    if (lb + 1 == rb) {
      Node* tmp = new Node(*this);
      tmp->val = d;
      return tmp;
    } else {
      Node* tmp = new Node(*this);
      if ((lb + rb) / 2 > id) {
        tmp->l = gl()->set(id, lb, (lb + rb) / 2, d);
      } else {
        tmp->r = gr()->set(id, (lb + rb) / 2, rb, d);
      }
      tmp->val = tmp->gl()->val + tmp->gr()->val;
      return tmp;
    }
  }
  Node* edit(long long id, long long lb, long long rb, ll d) {
    if (lb + 1 == rb) {
      Node* tmp = new Node(*this);
      tmp->val += d;
      return tmp;
    } else {
      Node* tmp = new Node(*this);
      if ((lb + rb) / 2 > id) {
        tmp->l = gl()->edit(id, lb, (lb + rb) / 2, d);
      } else {
        tmp->r = gr()->edit(id, (lb + rb) / 2, rb, d);
      }
      tmp->val = tmp->gl()->val + tmp->gr()->val;
      return tmp;
    }
  }
  ll get(long long lb, long long rb, long long l, long long r) {
    if (rb <= l || lb >= r) {
      return 0;
    }
    if (l <= lb && rb <= r) {
      return val;
    }
    return gl()->get(lb, (rb + lb) / 2, l, r) +
           gr()->get((lb + rb) / 2, rb, l, r);
  }
  Node() {}
};
vector<Node*> trees;
vector<Node*> names;
signed main() {
  trees.push_back(new Node());
  names.push_back(new Node());
  map<string, long long> mp;
  long long q, cnt = 0;
  cin >> q;
  for (long long i = 1; i <= q; ++i) {
    string s;
    cin >> s;
    if (s.front() == 's') {
      string ts;
      long long x;
      cin >> ts >> x;
      if (mp[ts] == 0) {
        mp[ts] = ++cnt;
      }
      ll k = names.back()->get(0, 1e9 + 1, mp[ts], mp[ts] + 1);
      names.push_back(names.back()->set(mp[ts], 0, 1e9 + 1, x));
      if (k) {
        trees.push_back(trees.back()->edit(k, 0, 1e9 + 1, -1));
        trees.back() = trees.back()->edit(x, 0, 1e9 + 1, 1);
      } else {
        trees.push_back(trees.back()->edit(x, 0, 1e9 + 1, 1));
      }
    } else if (s.front() == 'q') {
      string ts;
      cin >> ts;
      if (mp[ts]) {
        ll t = names.back()->get(0, 1e9 + 1, mp[ts], mp[ts] + 1);
        if (t == 0) {
          cout << -1 << endl << flush;
        } else {
          if (trees.back()->get(0, 1e9 + 1, 0, t) == -3) {
            cout << ts << endl;
          } else {
            cout << trees.back()->get(0, 1e9 + 1, 0, t) << endl << flush;
          }
        }
      } else {
        cout << -1 << endl << flush;
      }
      names.push_back(names.back());
      trees.push_back(trees.back());
    } else if (s.front() == 'r') {
      string ts;
      cin >> ts;
      if (mp[ts]) {
        ll t = names.back()->get(0, 1e9 + 1, mp[ts], mp[ts] + 1);
        if (t != 0) {
          trees.push_back(trees.back()->edit(t, 0, 1e9 + 1, -1));
          names.push_back(names.back()->set(mp[ts], 0, 1e9 + 1, 0));
        } else {
          names.push_back(names.back());
          trees.push_back(trees.back());
        }
      } else {
        names.push_back(names.back());
        trees.push_back(trees.back());
      }
    } else {
      ll d;
      cin >> d;
      trees.push_back(trees[i - d - 1]);
      names.push_back(names[i - d - 1]);
    }
  }
}
