#include <iostream>
#define BLACK true
#define RED false
using namespace std;
template <typename T>
struct Node{
  T key;
  
  bool color;
  Node<T> *p, *left, *right;
  Node(int _key): key(_key) {}
  Node(int _key, bool _color): key(_key), color(_color) {}
};
template <typename T>
class RBTree{
public:
  RBTree(void){
    nil=new Node<T>(-1);
  }
  
  Node<T>* Minimum(Node<T>* x){
    while(x->left!=this->nil) x=x->left;
    return x;
  }
  
  void LeftRotate(Node<T>* x){
    Node<T>* y=x->right;
    x->right=y->left;
    if(y->left==this->nil) y->left->p=x;
    y->p=x->p;
    if(x->p==this->nil) this->root=y;
    else if(x==x->p->left) x->p->left=y;
    else x->p->right=y;
    y->left=x;
    x->p=y;
  }
  
  void RightRotate(Node<T>* y){
    Node<T>* x=y->left;
    y->left=x->right;
    if(x->right==this->nil) x->right->p=y;
    x->p=y->p;
    if(y->p==this->nil) this->root=x;
    else if(y==y->p->right) y->p->right=x;
    else y->p->left=x;
    x->right=y;
    y->p=x;
  }
  
  void RBInsertFixup(Node<T>* z){
    Node<T>* y;
    while(z->p->color==RED){
      if(z->p==z->p->p->left){
        y=z->p->p->right;
        if(y->color==RED){
          z->p->color=BLACK;
          y->color=BLACK;
          z->p->p->color=RED;
          z=z->p->p;
        } else if(z==z->p->right){
          z=z->p;
          LeftRotate(z);
        } else {
          z->p->color=BLACK;
          z->p->p->color=RED;
          RightRotate(z->p->p);
        }
      } else {
        y=z->p->p->left;
        if(y->color==RED){
          y->p->color=BLACK;
          y->color=BLACK;
          z->p->p->color=RED;
          z=z->p->p;
        } else if(z==z->p->left){
          z=z->p;
          RightRotate(z);
        } else {
          z->p->color=BLACK;
          z->p->p->color=RED;
          LeftRotate(z->p->p);
        }
      }
    }
    this->root->color=BLACK;
  }
  
  void Insert(int key){
    Node<T>* z=new Node<T>(key, RED);
    Node<T> *x, *y;
    x=this->nil; y=this->root;
    while(x!=this->nil){
      y=x;
      if(z->key<x->key) x=x->left;
      else x=x->right;
    }
    z->p=y;
    if(y==this->nil) this->root=z;
    else if(z->key<y->key) y->left=z;
    else y->right=z;
    z->left=this->nil;
    z->right=this->nil;
    RBInsertFixup(z);
  }
  
  void Transplant(Node<T>* u, Node<T>* v){
    if(u->p==this->nil) this->root=v;
    else if(u==u->p->left) u->p->left=v;
    else u->p->right=v;
    v->p=u->p;
  }
  
  void DeleteFixup(Node<T>* x){
    Node<T>* w;
    while(x!=this->root && x->color==BLACK){
      if(x==x->p->left){
        w=x->p->right;
        if(w->color==RED){
          w->color=BLACK;
          x->p->color=RED;
          LeftRotate(x->p);
          w=x->p->right;
        }
        if(w->left->color==BLACK && w->right->color==BLACK){
          w->color=RED;
          x=x->p;
        } else if(w->right->color==BLACK){
          w->left->color=BLACK;
          w->color=RED;
          RightRotate(w);
          w=x->p->right;
        } else {
          w->color=x->p->color;
          x->p->color=BLACK;
          w->right->color=BLACK;
          LeftRotate(x->p);
          x=this->root;
        }
      } else {
        w=x->p->left;
        if(w->color==RED){
          w->color=BLACK;
          x->p->color=RED;
          RightRotate(x->p);
          w=x->p->left;
        }
        if(w->right->color==BLACK && w->left->color==BLACK){
          w->color=RED;
          x=x->p;
        } else if(w->left->color==BLACK){
          w->right->color=BLACK;
          w->color=RED;
          LeftRotate(w);
          w=x->p->left;
        } else {
          w->color=x->p->color;
          x->p->color=BLACK;
          w->left->color=BLACK;
          RightRotate(x->p);
          x=this->root;
        }
      }
    }
    x->color=BLACK;
  }
  
  void Delete(Node<T>* z){
    Node<T>* x;
    Node<T>* y=z;
    bool y_original_color=y->color;
    if(z->left==this->nil){
      x=z->right;
      Transplant(z, z->right);
    } else if(z->right==this->nil){
      x=z->left;
      Transplant(z, z->left);
    } else {
      y=Minimum(z->right);
      y_original_color=y->color;
      x=y->right;
      if(y->p==z) x->p=y;
      else{
        Transplant(y, y->right);
        y->right=z->right;
        y->right->p=y;
      }
      Transplant(z, y);
      y->left=z->lef;
      y->left->p=y;
      y->color=z->color;
    }
    if(y_original_color==BLACK) DeleteFixup(x);
    delete z;
  }
private:
  Node<T> *root, *nil;
};