// Copyright 2018 PETRASCO SANDU
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#define MAP_SIZE 99991
using namespace std;
template <typename TK, typename TV>
class node{
public:
TK key;
TV value;
node() = default;
node(const TK &, const TV &);
node(const node &);
TK& getKey() const;
TV& getValue() const;
void setValue(const TV &);
~node() = default;
};
template <typename TK, typename TV, typename TF>
class myMap{
vector < list < node<TK, TV> > > Bucket;
TF hashFoo;
public:
myMap();
void put(const TK &, const TV &);
void remove(const TK &);
TV get(const TK &);
bool isMapped(const TK &);
~myMap() = default;
};
template <typename TK, typename TV>
node<TK, TV>::node(const TK &_key, const TV &_value)
: key(_key)
, value(_value)
{}
template <typename TK, typename TV>
node<TK, TV>::node(const node &other){
key = other.key;
value = other.value;
}
template <typename TK, typename TV>
TK& node<TK, TV>::getKey() const{
return key;
}
template <typename TK, typename TV>
TV& node<TK, TV>::getValue() const{
return value;
}
template <typename TK, typename TV>
void node<TK, TV>::setValue(const TV &_value){
value = _value;
}
template <typename TK, typename TV, typename TF>
myMap<TK, TV, TF>::myMap(){
Bucket.resize(MAP_SIZE);
}
template <typename TK, typename TV, typename TF>
void myMap<TK, TV, TF>::put(const TK &key, const TV &value){
unsigned int index = hashFoo(key);
bool marked = 0;
for (auto it : Bucket[index]){
if (it.key == key){
it.value = value;
marked = 1;
}
}
if (marked == 0){
node<TK, TV> elem(key, value);
Bucket[index].push_back(elem);
}
}
template <typename TK, typename TV, typename TF>
void myMap<TK, TV, TF>::remove(const TK &key){
unsigned int index = hashFoo(key);
for (auto it : Bucket[index]){
if (it.key == key){
break;
}
}
Bucket[index].pop_back();
}
template <typename TK, typename TV, typename TF>
TV myMap<TK, TV, TF>::get(const TK &key){
unsigned int index = hashFoo(key);
TV value = TV();
for (auto it : Bucket[index]){
if (it.key == key){
value = it.value;
break;
}
}
return value;
}
template <typename TK, typename TV, typename TF>
bool myMap<TK, TV, TF>::isMapped(const TK &key){
unsigned int index = hashFoo(key);
for (auto it : Bucket[index]){
if (it.key == key){
return true;
}
}
return false;
}
struct myPair{
int first, second;
unsigned int operator()(const myPair &other) const{
return (other.first + other.second) % MAP_SIZE;
}
bool operator== (const myPair &other){
return first == other.first && second == other.second;
}
};
struct intHash{
unsigned int operator()(const int &nbr) const{
return nbr % MAP_SIZE;
}
};
struct stringHash{
unsigned int operator()(const string &str) const{
if (str.empty()) return 0;
unsigned int Power[str.size()];
unsigned int result;
Power[0] = 1;
result = (unsigned int)str[0];
for (unsigned int i = 1; i < str.size(); i++){
Power[i] = 255 * Power[i - 1] % MAP_SIZE;
result = result + ((unsigned int)str[i] * Power[i]) % MAP_SIZE;
result %= MAP_SIZE;
}
return result;
}
};
int n, t, x, idx = 0;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
ifstream cin("hashuri.in");
ofstream cout("hashuri.out");
cin >> n;
myMap < int , int , intHash > M;
while (n--){
cin >> t >> x;
if (t == 1 && M.isMapped(x)) continue;
if (t == 1) M.put(x, ++idx);
if (t == 2 && !M.isMapped(x)) continue;
if (t == 2) M.remove(x);
if (t == 3) cout << M.isMapped(x) << "\n";
}
return 0;
}