#include <bits/stdc++.h>
 
using namespace std;

#define pb push_back
#define mp make_pair
#define ll long long
#define int ll
#define ld long double
#define reps(i,s,n) for(int i=(s);i<(int)(n);i++) 
#define rep(i,n) reps(i,0,n)
#define rreps(i,s,n) for(int i=(int)(s-1);i>=n;i--) 
#define rrep(i,n) rreps(i,n,0)
#define all(v) (v).begin(),(v).end()
#define mset(a,n) memset(a,n,sizeof(a))
#define eras(v,n) (v).erase(remove(all(v),n),(v).end())
#define uni(v) sort(all(v));(v).erase(unique(all(v)),(v).end())
#define bcnt(i)  __builtin_popcount(i)
#define fi first
#define se second
constexpr ll INF = 1e18;
constexpr ll MOD = 1000000007;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
template<class T>T min(vector<T> &v) { return *min_element(v.begin(),v.end()); }
template<class T>T max(vector<T> &v) { return *max_element(v.begin(),v.end()); }
template<class T>T modpow(T a, T b, T m) { a %= m; T r = 1; while (b > 0) { if (b & 1) r = (r * a) % m; a = (a * a) % m; b >>= 1; } return r; }
ll modinv(ll a,ll m=MOD) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
template<class T>string radixconv(T n, T k){ string s; while(n/k){ s=to_string(n%k)+s; n/=k; } s=to_string(n%k)+s; return s; }

int32_t main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout << fixed << setprecision(11);
    cerr << fixed << setprecision(6);
    int ans=INF;
    int n;
    cin >> n;
    vector<int> a(n),b(n);
    rep(i,n){
        cin >> a[i] >> b[i];
        chmin(ans,a[i]+b[i]);
    }
    rep(i,n)rep(j,n)if(i!=j)chmin(ans,(int)max(a[i],b[j]));
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

#define rep(i, n) for(int i = 0;i < n;i++)
#define rep1(i, n) for(int i = 1;i < n;i++)
#define repr(i, n) for(int i = n;i >= 0;i--)
#define FOR(i, m, n) for(int i = m;i < n;i++)

#define ALL(a)  (a).begin(),(a).end()

vector<vector<ll>> near8={{-1,1},{0,1},{1,1},{-1,0},{1,0},{-1,-1},{0,-1},{1,-1}};
vector<vector<ll>> near4={{0,1},{-1,0},{1,0},{0,-1}};

ll INF = INT64_MAX;

bool ll_sqrt(ll x, ll& lower_bound, ll& upper_bound)
{
	constexpr ll ll_max = numeric_limits<ll>::max();
 
	bool first_boost = true;
 
	lower_bound = 0;
	upper_bound = x;
	while (upper_bound - lower_bound > 1)
	{
		if (first_boost)
		{
			ll guess = (ll)sqrt((double)x);
			lower_bound = max(guess - 1, (ll)0);
			upper_bound = lower_bound + 3;
			first_boost = false;
		}
 
		ll newval = (lower_bound + upper_bound) / 2;
		if ((newval != 0) && (newval > ll_max / newval))  // newval*newval becomes overflow
			upper_bound = newval;  // because overflow means newval is too big
		else
		{
			ll newval_sqr = newval * newval;
			if (newval_sqr < x)
				lower_bound = newval;
			else
				upper_bound = newval;
		}
	}
 
	if ((upper_bound != 0) && (upper_bound > ll_max / upper_bound))
	{
		if (lower_bound * lower_bound == x)
			upper_bound = lower_bound;
	}
	else
	{
		if (lower_bound * lower_bound == x)
			upper_bound = lower_bound;
		else if (upper_bound * upper_bound == x)
			lower_bound = upper_bound;
	}
	bool is_exact = (lower_bound == upper_bound);
	return is_exact;
}

ll ll_ceil(ll x, int digit);
ll ll_floor(ll x, int digit);


ll ll_floor(ll x, int digit)
{
	if (x < 0)
		return -ll_ceil(-x, digit);
 
	ll div = 1;
	while (digit != 0)
	{
		div *= 10;
		digit--;
	}
	ll modval = x % div;
	ll ans = x - modval;
	return ans;
}

ll ll_ceil(ll x, int digit)
{
	if (x < 0)
		return -ll_floor(-x, digit);
 
	ll div = 1;
	while (digit != 0)
	{
		div *= 10;
		digit--;
	}
	ll modval = x % div;
	ll ans = x - modval;
	if (modval != 0)
		ans += div;
	return ans;
}

struct UnionFind {
    vector<ll> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

    UnionFind(ll N) : par(N) { //最初は全てが根であるとして初期化
        for(ll i = 0; i < N; i++) par[i] = i;
    }

    ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(ll x, ll y) { // xとyの木を併合
        ll rx = root(x); //xの根をrx
        ll ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(ll x, ll y) { // 2つのデータx, yが属する木が同じならtrueを返す
        ll rx = root(x);
        ll ry = root(y);
        return rx == ry;
    }
};

ll H,W;
vector<vector<char>> map1(501, vector<char>(501,'#'));


bool solve(ll h, ll w){
	ll nexth=0;
	ll nextw=0;

	for(vector<ll> to:near4){
		nexth = h+to[0];
		nextw = w+to[1];
		if(nexth < 0 || nexth >=H || nextw < 0 || nextw >=W || map1[nexth][nextw] == '#'){
			continue;
		}
		if(map1[nexth][nextw] =='g'){
			return true;
		}
		map1[nexth][nextw]='#';
		if(solve(nexth, nextw)){
			return true;
		};
	}

	return false;
}


int main() {
	ll N;
	cin >> N;

	ll A[N];
	ll in ;

	UnionFind nums(200002);

	rep(i,N){
		cin >> A[i];
	}

	ll ans=0;

	ll a, b;
	rep(i, N/2){
		a = A[i];
		b = A[N-i-1];
		if(!nums.same(a,b)){
			ans++;
			nums.unite(a,b);
		}
	}


	cout << ans << endl;

  return 0;
}