#include <bits/stdc++.h>
using namespace std;
template <class T>
using vv = vector<vector<T>>;
template <class T>
ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "{";
  for (int(i) = 0; (i) < (t.size()); ++(i)) {
    os << t[i] << ",";
  }
  os << "}" << endl;
  return os;
}
template <class T, size_t n>
ostream &operator<<(ostream &os, const array<T, n> &t) {
  os << "{";
  for (int(i) = 0; (i) < (n); ++(i)) {
    os << t[i] << ",";
  }
  os << "}" << endl;
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
template <class S, class T, class U>
ostream &operator<<(ostream &os, const tuple<S, T, U> &t) {
  return os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
}
template <class S, class T, class U, class V>
ostream &operator<<(ostream &os, const tuple<S, T, U, V> &t) {
  return os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ","
            << get<3>(t) << ")";
}
template <class S, class T, class U, class V, class W>
ostream &operator<<(ostream &os, const tuple<S, T, U, V, W> &t) {
  return os << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ","
            << get<3>(t) << "," << get<4>(t) << ")";
}
template <class T>
inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T>
inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}
const long long MOD = 1e9 + 7;
struct UF {
  vector<int> data;
  UF(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
int main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(0);
  int n;
  scanf("%d", &n);
  vector<pair<int, int>> ps(n);
  vector<int> xs;
  for (int(i) = 0; (i) < (n); ++(i)) {
    int a, b;
    scanf("%d%d", &a, &b);
    ps[i] = pair<int, int>(a, b);
    xs.push_back(a);
    xs.push_back(b);
  }
  sort((xs).begin(), (xs).end());
  (xs).erase(unique((xs).begin(), (xs).end()), (xs).end());
  for (pair<int, int> &p : ps) {
    int a = lower_bound((xs).begin(), (xs).end(), p.first) - xs.begin();
    int b = lower_bound((xs).begin(), (xs).end(), p.second) - xs.begin();
    if (a > b) swap(a, b);
    p = pair<int, int>(a, b);
  }
  int m = xs.size();
  UF uf(m);
  for (pair<int, int> p : ps) uf.unite(p.first, p.second);
  vector<int> cnt(m), mx(m), mx2(m);
  auto upd = [&](int t, int x) {
    if (mx[t] == x || mx2[t] == x) return;
    if (mx[t] < x) {
      mx2[t] = mx[t];
      mx[t] = x;
    } else if (mx2[t] < x) {
      mx2[t] = x;
    }
  };
  for (pair<int, int> p : ps) {
    int t = uf.root(p.first);
    ++cnt[t];
    upd(t, p.first);
    upd(t, p.second);
  }
  (cnt, mx, mx2, 1);
  int ok = 1;
  int re = 0;
  for (int(i) = 0; (i) < (m); ++(i))
    if (uf.root(i) == i) {
      if (uf.size(i) == cnt[i]) {
        MX(re, mx[i]);
      } else if (uf.size(i) - 1 == cnt[i]) {
        MX(re, mx2[i]);
      } else
        ok = 0;
    }
  cout << (ok ? xs[re] : -1) << endl;
  return 0;
}
