#include <bits/stdc++.h>
using namespace std;
int M;
class Reader {
public:
Reader(const string& filename):
m_stream(filename),
m_pos(kBufferSize - 1),
m_buffer(new char[kBufferSize]) {
next();
}
Reader& operator>>(int& value) {
value = 0;
while (current() < '0' || current() > '9')
next();
while (current() >= '0' && current() <= '9') {
value = value * 10 + current() - '0';
next();
}
return *this;
}
private:
const int kBufferSize = 32768;
char current() {
return m_buffer[m_pos];
}
void next() {
if (!(++m_pos != kBufferSize)) {
m_stream.read(m_buffer.get(), kBufferSize);
m_pos = 0;
}
}
ifstream m_stream;
int m_pos;
unique_ptr<char[]> m_buffer;
};
struct Node {
int pr, value, size;
Node *l, *r;
Node(int pr = 0, int value = 0, int size = 0, Node *l = 0, Node *r = 0):
pr(pr),
value(value),
size(size),
l(l),
r(r) {
}
} *root, *nil;
void updateNode(Node *node) {
if (node == nil)
return;
node->size = 1 + node->l->size + node->r->size;
}
Node *unionTreaps(Node *l, Node *r) {
if (l == nil && r == nil)
return nil;
if (l == nil)
return r;
if (r == nil)
return l;
if (l->pr > r->pr) {
l->r = unionTreaps(l->r, r);
updateNode(l);
return l;
}
r->l = unionTreaps(l, r->l);
updateNode(r);
return r;
}
pair<Node *, Node *> splitTreaps(Node *node, int pos) {
if (node == nil)
return {nil, nil};
if (pos <= node->l->size) {
auto split = splitTreaps(node->l, pos);
node->l = split.second;
updateNode(node);
updateNode(split.first);
return {split.first, node};
}
auto split = splitTreaps(node->r, pos - 1 - node->l->size);
node->r = split.first;
updateNode(node);
updateNode(split.second);
return {node, split.second};
}
int getPos(Node *node, int value, bool &found) {
if (node == nil)
return 0;
if (value == node->value) {
found = 1;
return 1 + node->l->size;
}
if (value < node->value)
return getPos(node->l, value, found);
return 1 + node->l->size + getPos(node->r, value, found);
}
bool countValue(Node *node, int value) {
if (node == nil)
return 0;
if (value == node->value)
return 1;
if (value < node->value)
return countValue(node->l, value);
return countValue(node->r, value);
}
int main() {
assert(freopen("hashuri.in", "r", stdin));
assert(freopen("hashuri.out", "w", stdout));
srand(time(0));
root = nil = new Node(-1);
nil->l = nil->r = nil;
Reader cin("hashuri.in");
cin >> M;
while (M--) {
int type, x;
cin >> type >> x;
if (type == 1) {
bool found = 0;
int pos = getPos(root, x, found);
if (found)
continue;
Node *temp = new Node(rand(), x, 1, nil, nil);
auto split = splitTreaps(root, pos);
root = unionTreaps(unionTreaps(split.first, temp), split.second);
} else if (type == 2) {
bool found = 0;
int pos = getPos(root, x, found);
if (found == 0)
continue;
auto split1 = splitTreaps(root, pos - 1);
auto split2 = splitTreaps(split1.second, 1);
delete split2.first;
root = unionTreaps(split1.first, split2.second);
} else {
bool found = 0;
getPos(root, x, found);
cout << (found ? 1 : 0) << '\n';
}
}
return 0;
}