#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <vector>
#include <algorithm>
using namespace std;
struct TreapNode {
int key, priority;
TreapNode *left, *right;
};
TreapNode* rightRotate(TreapNode* y) {
TreapNode *x = y->left;
TreapNode *T2 = x->right;
x->right = y;
y->left = T2;
return x;
}
TreapNode* leftRotate(TreapNode* x) {
TreapNode *y = x->right;
TreapNode *T2 = y->left;
y->left = x;
x->right = T2;
return y;
}
TreapNode* newNode(int key) {
TreapNode* temp = new TreapNode;
temp->key = key;
temp->priority = rand() % 1000;
temp->left = temp->right = nullptr;
return temp;
}
TreapNode* insert(TreapNode* root, int key) {
if (root == nullptr) return newNode(key);
if (key <= root->key) {
root->left = insert(root->left, key);
if (root->left->priority > root->priority)
root = rightRotate(root);
} else {
root->right = insert(root->right, key);
if (root->right->priority > root->priority)
root = leftRotate(root);
}
return root;
}
TreapNode* deleteNode(TreapNode* root, int key) {
if (!root) return root;
if (key < root->key) root->left = deleteNode(root->left, key);
else if (key > root->key) root->right = deleteNode(root->right, key);
else {
if (!root->left) {
TreapNode* temp = root->right;
delete root;
return temp;
} else if (!root->right) {
TreapNode* temp = root->left;
delete root;
return temp;
} else if (root->left->priority < root->right->priority) {
root = leftRotate(root);
root->left = deleteNode(root->left, key);
} else {
root = rightRotate(root);
root->right = deleteNode(root->right, key);
}
}
return root;
}
TreapNode* mergeTreaps(TreapNode* left, TreapNode* right) {
if (!left) return right;
if (!right) return left;
if (left->priority > right->priority) {
left->right = mergeTreaps(left->right, right);
return left;
} else {
right->left = mergeTreaps(left, right->left);
return right;
}
}
void split(TreapNode* root, int key, TreapNode*& left, TreapNode*& right) {
if (!root) left = right = nullptr;
else if (root->key <= key) {
split(root->right, key, root->right, right);
left = root;
} else {
split(root->left, key, left, root->left);
right = root;
}
}
bool contains(TreapNode* root, int key) {
if (root == nullptr) return false;
if (root->key == key) return true;
if (key < root->key) return contains(root->left, key);
return contains(root->right, key);
}
TreapNode* findMaxLessThanEqual(TreapNode* root, int X) {
TreapNode* result = nullptr;
while (root) {
if (root->key <= X) {
result = root;
root = root->right;
} else {
root = root->left;
}
}
return result;
}
TreapNode* findMinGreaterThanEqual(TreapNode* root, int X) {
TreapNode* result = nullptr;
while (root) {
if (root->key >= X) {
result = root;
root = root->left;
} else {
root = root->right;
}
}
return result;
}
void findRange(TreapNode* root, int X, int Y, vector<int>& result) {
if (!root) return;
if (root->key > Y) {
findRange(root->left, X, Y, result);
} else if (root->key < X) {
findRange(root->right, X, Y, result);
} else {
findRange(root->left, X, Y, result);
result.push_back(root->key);
findRange(root->right, X, Y, result);
}
}
int main() {
srand(time(NULL));
// Citirea datelor de intrare
int Q;
cin >> Q;
TreapNode* root = nullptr;
while (Q--) {
int op, X, Y;
cin >> op;
if (op == 1) {
cin >> X;
root = insert(root, X);
} else if (op == 2) {
cin >> X;
root = deleteNode(root, X);
} else if (op == 3) {
cin >> X;
cout << (contains(root, X) ? 1 : 0) << "\n";
} else if (op == 4) {
cin >> X;
TreapNode* res = findMaxLessThanEqual(root, X);
cout << (res ? res->key : -1) << "\n";
} else if (op == 5) {
cin >> X;
TreapNode* res = findMinGreaterThanEqual(root, X);
cout << (res ? res->key : -1) << "\n";
} else if (op == 6) {
cin >> X >> Y;
vector<int> result;
findRange(root, X, Y, result);
for (int num : result) cout << num << " ";
cout << "\n";
}
}
return 0;
}