#include <bits/stdc++.h>   using namespace std;   const int N = 2e6 + 100, M = 1e6 + 100;   int n, up[N], down[M], nei[M][2];   int lim;   bool mark[M], bad[M];   vector<int> vec;   int f(int a) { return lower_bound(vec.begin(), vec.end(), a) - vec.begin(); }   bool dfs(int v) {     mark[v] = true;     for (int i = 0; i < 2 && nei[v][i] <= lim; i++) {       int u = nei[v][i];       if (up[u] == -1 || (mark[up[u]] == false && dfs(up[u]))) {         up[u] = v;         down[v] = u;         return true;       }     }     return false;   }   bool ok(int X) {     lim = X;     fill(up, up + N, -1);     fill(down, down + M, -1);     memset(bad, false, sizeof bad);     int matching = 0;     bool done = false;     for (int v = 0; v < n; v++)       if (nei[v][0] > lim)         return false;       else if (nei[v][1] > lim) {         if (up[nei[v][0]] != -1) return false;         down[v] = nei[v][0];         up[nei[v][0]] = v;         bad[v] = true;         matching++;       }     while (done == false) {       done = true;       copy(bad, bad + n, mark);       for (int v = 0; v < n; v++)         if (mark[v] == false && down[v] == -1 && dfs(v)) {           matching++;           done = false;         }     }     return matching == n;   }   int main() {     ios::sync_with_stdio(false), cin.tie(0);     cin >> n;     for (int i = 0; i < n; i++) {       cin >> nei[i][0] >> nei[i][1];       vec.push_back(nei[i][0]);       vec.push_back(nei[i][1]);     }     sort(vec.begin(), vec.end());     vec.resize(unique(vec.begin(), vec.end()) - vec.begin());     for (int i = 0; i < n; i++)       nei[i][0] = f(nei[i][0]), nei[i][1] = f(nei[i][1]);     if (ok(vec.size() - 1) == false) {       cout << -1;       return 0;     }     if (ok(vec.size() - 2) == false) {       cout << vec.back();       return 0;     }     int l = -1, r = vec.size() - 1;     while (r - l > 1) {       if (ok((l + r) >> 1))         r = lim;       else         l = lim;     }     cout << vec[r];     return 0;   }   