#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <climits>
using namespace std;
int n, q;
struct cmp {
bool operator()(const int& st, const int& dr)const {
return st > dr;
}
};
multiset<int,cmp>heap[101];
ifstream fin("mergeheap.in");
ofstream fout("mergeheap.out");
int main()
{
fin >> n >> q;
for (int i = 1; i <= q; i++)
{
int cer;
fin >> cer;
switch (cer) {
case 1: {
int x, val;
fin >> x >> val;
heap[x].insert(val);
break;
}
case 2:
{
int x;
fin >> x;
fout << *heap[x].begin()<<"\n";
heap[x].erase(heap[x].begin());
break;
}
case 3: {
int x, y;
fin >> x >> y;
heap[x].insert(heap[y].begin(), heap[y].end());
heap[y].clear();
break;
}
};
}
return 0;
}