For a set $S$ of integers, perform a sequence of the following operations. Note that each value in $S$ must be unique.

* insert($x$): Insert $x$ to $S$ and report the number of elements in $S$ after the operation.
* find($x$): Report the number of $x$ in $S$ (0 or 1).
* delete($x$): Delete $x$ from $S$.

Constraints

* $1 \leq q \leq 200,000$
* $0 \leq x \leq 1,000,000,000$

Input

The input is given in the following format.


$q$
$query_1$
$query_2$
:
$query_q$


Each query $query_i$ is given by


0 $x$


or


1 $x$


or


2 $x$


where the first digits 0, 1 and 2 represent insert, find and delete operations respectively.

Output

For each insert operation, print the number of elements in $S$.
For each find operation, print the number of specified elements in $S$.

Example

Input

8
0 1
0 2
0 3
2 2
1 1
1 2
1 3
0 2


Output

1
2
3
1
0
1
3
#include <iostream>
#include <memory>
#include <random>
#include <limits>
#include <ctime>

template <class Key>
class Treap {
    struct Node {
        bool isvalid;  // falseなら空Node
        Key key;
        int priority;

        int sz;
        Key sum;

        std::unique_ptr<Node> lch, rch;
        Node() : isvalid(false), sz(0), sum(0) {}
        Node(Key key, int priority)
            : isvalid(true), key(key), priority(priority), sz(1), sum(key), lch(new Node()), rch(new Node()) {}
    };
    using pNode = std::unique_ptr<Node>;

private:
    pNode root;

    // 乱数生成
    std::mt19937 mt;
    std::uniform_int_distribution<> rnd;

    int count(pNode& node) { return node->sz; }
    Key sum(pNode& node) { return node->key; }

    pNode& update(pNode& node) {
        node->sz = count(node->lch) + count(node->rch) + 1;
        node->sum = sum(node->lch) + sum(node->rch) + node->key;
        return node;
    }

    pNode& rotateR(pNode& node) {
        pNode lnode = std::move(node->lch);
        node->lch = std::move(lnode->rch);
        update(node);
        lnode->rch = std::move(node);
        update(lnode);
        return node = std::move(lnode);
    }

    pNode& rotateL(pNode& node) {
        pNode rnode = std::move(node->rch);
        node->rch = std::move(rnode->lch);
        update(node);
        rnode->lch = std::move(node);
        update(rnode);
        return node = std::move(rnode);
    }

    pNode& insert(Key key, int priority, pNode& node) {
        if (!node->isvalid) {
            node.reset(new Node(key, priority));
            return node;
        }

        if (node->key == key) return node;

        if (key < node->key) {
            node->lch = std::move(insert(key, priority, node->lch));
            update(node);
            return (node->priority < node->lch->priority ? rotateR(node) : node);
        } else {
            node->rch = std::move(insert(key, priority, node->rch));
            update(node);
            return (node->priority < node->rch->priority ? rotateL(node) : node);
        }
    }

    bool find(Key key, pNode& node) {
        if (!node->isvalid) return false;
        if (key == node->key) return true;
        return find(key, (key < node->key ? node->lch : node->rch));
    }

    // 削除対象を見つける
    pNode& erase(Key key, pNode& node) {
        if (!node->isvalid) return node;

        if (key == node->key) {
            return match_erase(key, node);
        } else {
            if (key < node->key) {
                node->lch = std::move(erase(key, node->lch));
            } else {
                node->rch = std::move(erase(key, node->rch));
            }
            return update(node);
        }
    }

    // 見つけた削除対象を消す
    pNode& match_erase(Key key, pNode& node) {
        if (!node->lch->isvalid && !node->rch->isvalid) {
            node.reset(new Node());
            return node;
        }

        if (!node->lch->isvalid) {
            return erase(key, rotateL(node));
        } else if (!node->rch->isvalid) {
            return erase(key, rotateR(node));
        } else {
            if (node->lch->priority > node->rch->priority) {
                return erase(key, rotateR(node));
            } else {
                return erase(key, rotateL(node));
            }
        }
    }

public:
    explicit Treap() : root(new Node()), mt(int(std::time(nullptr))), rnd(0, std::numeric_limits<int>::max()) {}

    void insert(Key key) { insert(key, rnd(mt), root); }
    bool find(Key key) { return find(key, root); }
    void erase(Key key) { erase(key, root); }
    int getsize() { return root->sz; }
    int getsum() { return root->sum; }
};

int main() {
    Treap<int> s;
    int Q;
    std::cin >> Q;
    for (int q = 0; q < Q; ++q) {
        int t, x;
        std::cin >> t >> x;
        if (t == 0) {
            s.insert(x);
            std::cout << s.getsize() << std::endl;
        } else if (t == 1) {
            std::cout << s.find(x) << std::endl;
        } else {
            s.erase(x);
        }
    }
}
