/*
* Problem :: 7662 / 이중 우선순위 큐
*
* Kind :: Data Structure
*
* Insight
* - 최댓값과 최솟값을 항상 추적하고 있어야 한다
* + 우선순위큐를 활용하면 되지 않을까?
* MaxHeap, MinHeap 을 활용해보자
* # 근데... MaxHeap 에서 최댓값을 없애면
* MinHeap 에도 현재 최댓값을 없애야 하는데
* 방법이 없다! 그 역도 마찬가지
* + 다른 자료구조가 없을까?
* 자동정렬 + 최댓값과 최솟값에 항상 접근가능한 자료구조로는...
* Map 이 있구나!
* # Map 의 begin, end 를 활용해서 최댓값 최솟값에 접근하자!
*
* Point
* - MultiSet 으로도 구현가능하다
* + 코드길이는 줄어들지만 수행시간이 늘어난다
* # Map 688ms / MultiSet 1520ms
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <map>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int T; cin >> T;
while (T--) {
int K; cin >> K;
// Process
map<int,int> M;
for (int i=0; i<K; i++) {
char type; int n;
cin >> type >> n;
/* I n */
if (type == 'I') { M[n]++; }
/* D 1 */
else if (type == 'D' && n == 1) {
if (M.empty()) continue;
int maxi = (--M.end())->first;
int &num = (--M.end())->second;
num--;
if (num == 0) { M.erase(maxi); }
}
/* D -1 */
else if (type == 'D' && n == -1) {
if (M.empty()) continue;
int mini = (M.begin())->first;
int &num = (M.begin())->second;
num--;
if (num == 0) { M.erase(mini); }
}
}
// Control : Output
if (M.empty())
cout << "EMPTY" << endl;
else
cout << (--M.end())->first << ' ' << (M.begin())->first << endl;
}
}
// Helper Functions
/* None */