#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <iomanip>
using namespace std;
#define ll long long
#define ld long double
const ll MAXN = 1e6 + 5;
const ll moD = 1e9 + 7;
ll spf[MAXN];
ll power(ll base, ll exp, ll mod)
{
if (exp == 0)
return 1 % mod;
ll half = power(base, exp / 2, mod);
ll ans = (half * half) % mod;
if (exp % 2 == 1)
ans = (ans * base) % mod;
return ans;
}
ll gcd(ll a, ll b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
ll lcm(ll a, ll b)
{
return a / gcd(a, b) * b;
}
void sieve()
{
for (int i = 1; i < MAXN; i++)
spf[i] = i;
for (int p = 2; p * p < MAXN; p++)
{
if (spf[p] == p)
{
for (int i = p * p; i < MAXN; i += p)
{
if (spf[i] == i)
spf[i] = p;
}
}
}
}
vector<pair<ll, ll>> primeFactorization(ll x)
{
vector<pair<ll, ll>> factors;
while (x > 1)
{
ll prime = spf[x];
ll count = 0;
while (x % prime == 0)
{
count++;
x /= prime;
}
factors.emplace_back(prime, count);
}
return factors;
}
void generateDivisors(const vector<pair<ll, ll>> &factors, vector<ll> &divisors, ll current = 1, int index = 0)
{
if (index == factors.size())
{
divisors.push_back(current);
return;
}
ll prime = factors[index].first;
ll exp = factors[index].second;
for (int i = 0; i <= exp; i++)
{
generateDivisors(factors, divisors, current, index + 1);
current *= prime;
}
}
vector<ll> prefixSum(vector<ll> &v)
{
vector<ll> vc(v.size());
vc[0] = v[0];
for (int i = 1; i < v.size(); i++)
{
vc[i] = vc[i - 1] + v[i];
}
return vc;
}
ld Gamma(ld n)
{
return tgammal(n);
}
ld average(vector<ld> &vector)
{
if (vector.empty())
{
return 0.0;
}
ld sum = 0.0;
for (ld e : vector)
{
sum += e;
}
return static_cast<ld>(sum) / vector.size();
}
ll binarySearch(vector<ll> &v, ll target)
{
ll l = 0, r = v.size() - 1;
while (l <= r)
{
ll m = l + (r - l) / 2;
if (v[m] == target)
{
return m;
}
else if (v[m] < target)
l = m + 1;
else
r = m - 1;
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
// freopen("mex.in", "r", stdin);
ll n;
cin >> n;
vector<pair<ll, ll>> intervals(n);
for (int i = 0; i < n; i++)
{
cin >> intervals[i].first >> intervals[i].second;
}
sort(intervals.begin(), intervals.end());
long long current_min = intervals[0].first;
for (int i = 0; i < n - 1; i++)
{
long long curL = intervals[i].first;
long long curR = intervals[i].second;
long long nextL = intervals[i + 1].first;
if (curR + 1 < nextL)
{
cout << current_min << " " << curR << "\n";
current_min = nextL;
}
}
cout << current_min << " " << intervals.back().second << "\n";
return 0;
}