#include <math.h>
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
using ll = long long;
using ld = double;
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define F(i, l, r) for(int i = l; i < (r); ++i)
#define vpii vector<pii>
#define vpll vector<pll>
#define vll vector<ll>
#define vld vector<ld>
#define FD(i, r, l) for(int i = r; i > (l); --i)
#define G(x) int x; cin >> x;
#define GL(x) ll x; cin >> x;
#define GD(x) ld x; cin >> x;
#define GS(s) string s; cin >> s;
#define GC(c) char c; cin >> c;
#define fs first
#define sc second
#define inf 0x3f3f3f3f
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define pb push_back
#define size(x) (int)x.size()
#ifdef DEV_MODE
#include "debug.h"
#else
#define dbg(...)
#define dbg2d(...)
#endif
// #define int long long
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
G(q)
vector<vi> g;
g.pb({});
vector<vi> st;
st.pb({});
int v = 0;
vi col;
col.pb(-1);
vector<vector<int>> jump;
jump.pb(vi(22));
auto Add = [&](int i, int x) -> void {
int N = size(g);
v = N;
g[i].pb(N);
g.pb({});
st.pb({i});
col.pb(x);
jump.pb(vi(22));
jump[N][0] = i;
F(j, 1, 22) {
jump[N][j] = jump[jump[N][j - 1]][j - 1];
}
};
vi qs;
F(it, 0, q) {
GS(type)
if (type == "+") {
G(x)
Add(v, x);
} else if (type == "-") {
G(k)
int u = v;
FD(px, 21, -1) {
if (k >> px & 1) {
u = jump[u][px];
}
}
st[u].pb(v);
v = u;
} else if (type == "!") {
int u = st[v].back();
st[v].pop_back();
v = u;
} else {
qs.pb(v);
}
}
int n = size(g);
vi c(1000005);
int ans = 0;
vi b(n);
auto DFS = [&](auto DFS, int v) -> void {
if (v >= n) return;
if (c[col[v]] == 0) ans++;
c[col[v]]++;
b[v] = ans;
for (auto u : g[v]) {
DFS(DFS, u);
}
if (c[col[v]] == 1) ans--;
c[col[v]]--;
};
for (auto u : g[0]) {
DFS(DFS, u);
}
for (auto z : qs) {
cout << b[z] << '\n';
}
}