#include <bits/stdc++.h>
using namespace std;
struct Node {
int value, priority;
Node *left, *right;
Node(int value, int priority, Node *left, Node *right):
value(value),
priority(priority),
left(left),
right(right) {
}
} *root, *nil;
Node *unionTreaps(Node *left, Node *right) {
if (left == nil)
return right;
if (right == nil)
return left;
if (left->priority > right->priority) {
left->right = unionTreaps(left->right, right);
return left;
}
right->left = unionTreaps(left, right->left);
return right;
}
pair<Node *, Node *> splitTreaps(Node *node, int value) {
if (node == nil)
return {nil, nil};
if (value >= node->value) {
auto split = splitTreaps(node->right, value);
node->right = split.first;
return {node, split.second};
}
auto split = splitTreaps(node->left, value);
node->left = split.second;
return {split.first, node};
}
int countValue(Node *node, int value) {
if (node == nil)
return 0;
if (value == node->value)
return 1;
if (value < node->value)
return countValue(node->left, value);
return countValue(node->right, value);
}
int main() {
assert(freopen("hashuri.in", "r", stdin));
assert(freopen("hashuri.out", "w", stdout));
srand(time(0));
root = nil = new Node(0, 0, nullptr, nullptr);
nil->left = nil->right = nil;
int N;
for (scanf("%d", &N); N; --N) {
int operation, value;
scanf("%d %d", &operation, &value);
if (operation == 1) {
if (countValue(root, value))
continue;
Node *temp = new Node(value, rand(), nil, nil);
auto split = splitTreaps(root, value);
Node *newRoot = unionTreaps(split.first, temp);
root = unionTreaps(newRoot, split.second);
} else if (operation == 2) {
if (!countValue(root, value))
continue;
auto split = splitTreaps(root, value);
auto _split = splitTreaps(split.first, value - 1);
delete _split.second;
root = unionTreaps(_split.first, split.second);
} else {
cout << countValue(root, value) << '\n';
}
}
return 0;
}