#include <bits/stdc++.h>
#define VI vector<int>
#define VII vector<pair<int,int>>
#define QI queue<int>
#define ms(a,v) memset( a, v, sizeof( a ) )
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
#define ROF(i,a,b) for(int i = a; i >= b; i--)
#define foreach(v, c) for( typeof( (c).begin() ) v = (c).begin(); v != (c).end(); ++v)
#define pb push_back
#define pp pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define popcount __builtin_popcount
#define gcd __gcd
#define bit(n,i) ( n & ( 1LL << i ) )
#define lsb(x) ( x & ( -x ) )
#define FIN(str) freopen(str,"r",stdin)
#define FOUT(str) freopen(str,"w",stdout)
#define Fin(str) ifstream(str)
#define Fout(str) ostream(str)
#define SYNC ios_base::sync_with_stdio(0);
#define ll long long
#define ull unsigned long long
inline void read( int &a )
{
register char ch;
a = 0;
int sign = 1;
do
{
ch = getchar();
} while ( !isdigit( ch ) && ch != '-' );
if ( ch == '-' )
{
sign = -1;
ch = getchar();
}
do
{
a = a * 10 + ch - '0';
ch = getchar();
} while( isdigit( ch ) );
a *= sign;
}
inline void write( int a )
{
char s[20];
int i = 0;
int sign = 1;
if ( a < 0 )
sign = -1,
a = -a;
do
{
s[ i++ ] = a % 10 + '0';
a /= 10;
} while ( a );
i--;
if ( sign == -1 )
putchar( '-' );
while ( i >= 0 ) putchar( s[ i-- ] );
}
const int dx[] = { -1, 0, 1, 0 };
const int dy[] = { 0, 1, 0, -1 };
const int dl[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dc[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
const int INF = 2e9;
const double EPS = 1e-9;
const int Nmax = 1e4 + 2;
const int LgMax = log2(Nmax) + 1;
using namespace std;
template <typename T>
class SplayTree
{
public:
SplayTree();
SplayTree(vector<T> &v);
bool insert(const T& value);
bool find(const T& value);
bool erase(const T& value);
void inorder();
protected:
class Node
{
public:
Node(){}
T key;
Node *left, *right;
Node(const T& value);
Node(const T value, Node *_left, Node *_right);
void update();
};
Node *root, *NIL;
Node* rotateLeft(Node *root);
Node* rotateRight(Node *root);
Node* splay(Node *root, const T& value);
bool insert(Node *&root, const T& value);
bool find(Node *&root, const T& value);
bool erase(Node *&root, const T& value);
void inorder(Node *root);
};
///--------------------------------------------------------------------------------------
/// begin class Node implementation
template <typename T>
SplayTree<T>::Node::Node(const T& value)
{
this->key = value;
this->left = nullptr;
this->right = nullptr;
}
template <typename T>
SplayTree<T>::Node::Node(const T value, Node *_left, Node *_right)
{
this->key = value;
this->left = _left;
this->right = _right;
}
template <typename T>
void SplayTree<T>::Node::update()
{
}
template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::rotateRight(Node *N)
{
Node *aux = N->left;
N->left = aux->right;
aux->right = N;
aux->update();
N->update();
return aux;
}
template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::rotateLeft(Node *N)
{
Node *aux = N->right;
N->right = aux->left;
aux->left = N;
aux->update();
N->update();
return aux;
}
/// end class Node implementation
///--------------------------------------------------------------------------------------
template <typename T>
SplayTree<T>::SplayTree()
{
NIL = new Node(T());
this->root = NIL;
}
template <typename T>
typename SplayTree<T>::Node* SplayTree<T>::splay(Node *root, const T& value)
{
if ( root == NIL || root->key == value )
return root;
Node *leftTreeMax, *rightTreeMin;
static Node header;
header.left = header.right = NIL;
leftTreeMax = rightTreeMin = &header;
NIL->key = value;
while ( true )
{
if ( value == root->key ) break;
if ( value < root->key )
{
if ( value < root->left->key )
root = rotateRight(root);
if ( root->left == NIL ) break;
rightTreeMin->left = root;
rightTreeMin = root;
root = root->left;
}
else
{
if ( root->right->key < value )
root = rotateLeft(root);
if ( root->right == NIL ) break;
leftTreeMax->right = root;
leftTreeMax = root;
root = root->right;
}
}
leftTreeMax->right = root->left;
rightTreeMin->left = root->right;
root->left = header.right;
root->right = header.left;
return root;
}
template <typename T>
bool SplayTree<T>::insert(const T& value)
{
return insert(root, value);
}
template <typename T>
bool SplayTree<T>::insert(Node *&root, const T& value)
{
if ( root == NIL )
{
root = new Node(value);
root->left = root->right = NIL;
return true;
}
root = splay(root, value);
if ( root->key == value )
return false;
Node *newNode = new Node(value);
if ( value < root->key )
{
newNode->left = root->left;
newNode->right = root;
root->left = NIL;
root = newNode;
}
else
{
newNode->right = root->right;
newNode->left = root;
root->right = NIL;
root = newNode;
}
return true;
}
template <typename T>
bool SplayTree<T>::find(const T& value)
{
return find(root, value);
}
template <typename T>
bool SplayTree<T>::find(Node *&root, const T& value)
{
root = splay(root, value);
return ( root->key == value );
}
template <typename T>
bool SplayTree<T>::erase(const T& value)
{
return erase(root, value);
}
template <typename T>
bool SplayTree<T>::erase(Node *&root, const T& value)
{
if ( root == NIL )
return false;
Node *newNode, *aux = root;
root = splay(root, value);
if ( root->key != value )
return false;
if ( root->left == NIL )
newNode = root->right;
else
{
newNode = splay(root->left, value);
newNode->right = root->right;
}
delete root;
root = newNode;
return true;
}
template <typename T>
void SplayTree<T>::inorder(Node *root)
{
if ( root == NIL )
return;
inorder(root->left);
cout << root->key << " ";
inorder(root->right);
}
template <typename T>
void SplayTree<T>::inorder()
{
return inorder(root);
}
int main()
{
FIN("hashuri.in");
FOUT("hashuri.out");
int N, type, key;
read( N );
SplayTree <int> T;
for ( int k = 0; k < N; ++k )
{
read( type ); read( key );
if ( type == 1 )
{
T.insert(key);
}
if ( type == 2 )
{
T.erase(key);
}
if ( type == 3 )
{
printf("%d\n", T.find(key));
}
}
return 0;
}