//
// main.cpp
// Treaps
//
// Created by Vlad Turcuman on 30/05/2017.
// Copyright © 2017 Vlad Turcuman. All rights reserved.
//
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
ifstream cin ("zeap.in");
ofstream cout ("zeap.out");
#define inf 1000000000
struct Nod{
Nod *left, *right;
int key,priority;
Nod(int k,int p) { key = k, priority = p; left = right = NULL; Max = Min = k; MinDif = inf; MaxDif = 0;}
///
int Max,Min;
int MinDif;
int MaxDif;
};
void Update ( Nod * root)
{
if(root == NULL)
return;
root-> Min = root->key;
root-> Max = root->key;
root-> MinDif = inf;
root-> MaxDif = 0;
if(root->left != NULL)
{
root-> Min = min(root-> Min, root -> left -> Min);
root-> Max = max(root-> Max, root -> left -> Max);
root->MinDif = min(root->key - root -> left -> Max, root->left->MinDif);
root->MaxDif = root->key - root -> left -> Min;
}
if(root->right != NULL)
{
root-> Min = min(root-> Min, root -> right -> Min);
root-> Max = max(root-> Max, root -> right -> Max);
root->MinDif = min(root->MinDif, root->right->Min - root -> key);
root->MinDif = min(root->MinDif, root->right->MinDif);
root->MaxDif = root->right->Max - root -> key;
if(root->left != NULL)
root-> MaxDif = root->right->Max - root->left->Min;
}
}
void Split(Nod * root, int key, Nod *& left, Nod *& right)
{
left = right = root;
if(root == NULL)
return;
if(root -> key > key)
Split(root -> left, key, left, root -> left);
else
Split(root -> right, key, root -> right, right);
Update(root);
}
void Merge(Nod *& root, Nod * left, Nod * right)
{
if(left == NULL || right == NULL)
{
root = left == NULL ? right : left;
return;
}
if(left -> priority > right -> priority)
{
root = left;
Merge(root -> right, root -> right, right);
}
else
{
root = right;
Merge(root -> left, left, root -> left);
}
Update(root);
}
bool Check(Nod *&root, int key)
{
if(root == NULL)
return 0;
Nod * left = NULL, * right = NULL, * tmp = NULL;
Split(root, key, left, right);
Split(left, key-1, left, tmp);
Merge(root, left, tmp);
Merge(root, root, right);
if(tmp == NULL)
return 0;
return 1;
}
void Insert(Nod *&root, int key, int priority)
{
if(Check(root, key))
return;
Nod * left = NULL, * right = NULL;
Split(root,key,left,right);
Merge(root, left, new Nod(key,priority));
Merge(root, root, right);
}
void Erase(Nod *&root, int key)
{
if(!Check(root, key))
{
cout<<-1<<'\n';
return ;
}
Nod * left = NULL, * right = NULL, * tmp = NULL;
Split(root, key, left, right);
Split(left, key - 1, left, tmp);
delete tmp;
Merge(root, left, right);
}
int main()
{
srand(time(NULL));
Nod * root = NULL;
char ch;
int value;
while(cin>>ch)
{
if(ch == 'M')
{
cin>>ch>>ch;
if(ch == 'X')
{
if(root->MaxDif == 0)
cout<<-1<<'\n';
else
cout<<root->MaxDif<<'\n';
}
else
{
if(root->MinDif == inf)
cout<<-1<<'\n';
else
cout<<root->MinDif<<'\n';
}
continue;
}
cin>>value;
if(ch == 'I')
Insert(root, value, rand());
if(ch == 'S')
Erase(root, value);
if(ch == 'C')
cout<<Check(root, value)<<'\n';
}
return 0;
}
/*
I 3
I 4
I 2
C 4
Max
Min
C 2
*/