#include <bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
using namespace std;
inline long long rint() {
  long long x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
long long gcd(long long a, long long b) { return (b) ? gcd(b, a % b) : a; }
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
long long pow(long long a, long long b, long long q) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % q;
    a = a * a % q;
    b >>= 1;
  }
  return ans;
}
const long long mod = 998244353;
const long long N = 2e6 + 5;
int father[N];
void build(int n) {
  for (int i = 0; i < n; i++) father[i] = i;
}
int findroot(int in) {
  return father[in] == in ? in : father[in] = findroot(father[in]);
}
void merge(int x, int y) {
  if (findroot(x) == findroot(y)) return;
  father[findroot(x)] = findroot(y);
}
int bian[N];
struct Node {
  int size, zuida, cida;
};
int main() {
  int n = rint();
  vector<pair<int, int>> v(n);
  for (int i = 0; i < n; i++) v[i].first = rint(), v[i].second = rint();
  vector<int> t;
  for (int i = 0; i < n; i++) t.push_back(v[i].first), t.push_back(v[i].second);
  sort((t).begin(), (t).end());
  t.erase(unique((t).begin(), (t).end()), t.end());
  map<int, int> lisanhua;
  for (int i = 0; i < t.size(); i++) lisanhua[t[i]] = i;
  for (int i = 0; i < n; i++)
    v[i].first = lisanhua[v[i].first], v[i].second = lisanhua[v[i].second];
  build((int)t.size());
  for (int i = 0; i < n; i++) merge(v[i].first, v[i].second);
  for (int i = 0; i < n; i++) bian[findroot(v[i].first)]++;
  map<int, Node> mp;
  for (int i = 0; i < t.size(); i++) {
    if (mp.find(findroot(i)) == mp.end()) {
      Node node;
      node.size = 0;
      node.cida = 0;
      node.zuida = 0;
      mp[findroot(i)] = node;
    }
    Node node = mp[findroot(i)];
    node.size++;
    node.cida = max(node.cida, i);
    if (node.cida > node.zuida) swap(node.cida, node.zuida);
    mp[findroot(i)] = node;
  }
  int res = 0;
  for (auto i : mp) {
    if (bian[i.first] > i.second.size)
      return puts("-1");
    else if (bian[i.first] == i.second.size)
      res = max(res, i.second.zuida);
    else
      res = max(res, i.second.cida);
  }
  cout << t[res] << "\n";
}
