//#define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#if __cplusplus < 201500L
#include <bits/stdc++.h>
#else
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <cmath>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>
#endif

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef map<string, int> mpsi;
typedef map<double, int> mpdi;
typedef map<int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 1 }, {
		1, 1 }, { 1, -1 }, { -1, -1 } };

template<class T> inline T abs1(T a) {
	return a < 0 ? -a : a;
}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template<typename t, typename t1>
t min1(t a, t1 b) {
	return a < b ? a : b;
}
template<typename t, typename ... arg>
t min1(t a, arg ... arr) {
	return min1(a, min1(arr...));
}
template<typename t, typename t1>
t max1(t a, t1 b) {
	return a > b ? a : b;
}
template<typename t, typename ... arg>
t max1(t a, arg ... arr) {
	return max1(a, max1(arr...));
}
#endif

inline int jud(double a, double b) {
	if (abs(a) < eps && abs(b) < eps)
		return 0;
	else if (abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if (a < b) return -1;
	return 1;
}
template<typename t> inline int jud(t a, t b) {
	if (a < b) return -1;
	if (a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template<typename it, typename t1>
inline int RangeFind(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1) {
	if (na == 0) return 0;
	int be = 0, en = na - 1;
	if (*a <= *(a + na - 1)) {
		if (f_lb == 0)
			while (be < en) {
				int mid = (be + en + 1) / 2;
				if (jud(*(a + mid), val) != 1)
					be = mid;
				else
					en = mid - 1;
			}
		else
			while (be < en) {
				int mid = (be + en) / 2;
				if (jud(*(a + mid), val) != -1)
					en = mid;
				else
					be = mid + 1;
			}
		if (f_small && jud(*(a + be), val) == 1) be--;
		if (!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if (f_lb)
			while (be < en) {
				int mid = (be + en + 1) / 2;
				if (jud(*(a + mid), val) != -1)
					be = mid;
				else
					en = mid - 1;
			}
		else
			while (be < en) {
				int mid = (be + en) / 2;
				if (jud(*(a + mid), val) != 1)
					en = mid;
				else
					be = mid + 1;
			}
		if (!f_small && jud(*(a + be), val) == -1) be--;
		if (f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template<class T> inline T lowb(T num) {
	return num & (-num);
}
#ifdef GPP
inline int bitnum(ui nValue) {
	return __builtin_popcount(nValue);
}
inline int bitnum(int nValue) {
	return __builtin_popcount(nValue);
}
inline int bitnum(ull nValue) {
	return __builtin_popcountll(nValue);
}
inline int bitnum(ll nValue) {
	return __builtin_popcountll(nValue);
}
inline int bitmaxl(ui a) {
	if (a == 0) return 0;
	return 32 - __builtin_clz(a);
}
inline int bitmaxl(int a) {
	if (a == 0) return 0;
	return 32 - __builtin_clz(a);
}
inline int bitmaxl(ull a) {
	if (a == 0) return 0;
	return 64 - __builtin_clzll(a);
}
inline int bitmaxl(ll a) {
	if (a == 0) return 0;
	return 64 - __builtin_clzll(a);
}
#else
#endif

long long pow(long long n, long long m, long long mod = 0) {
	if (m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while (m) {
		if (m & 1) {
			ans *= k;
			if (mod) ans %= mod;
		}
		k *= k;
		if (mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template<class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if (mod == -1) mod = MOD;
	a += b;
	while (a >= mod)
		a -= mod;
	while (a < 0)
		a += mod;
}
template<class t>
void output1(t arr) {
	for (int i = 0; i < (int) arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template<class t>
void output2(t arr) {
	for (int i = 0; i < (int) arr.size(); i++)
		output1(arr[i]);
}


//....................密..........封..........线..........下..........禁..........止..........hack...............................................

#ifndef SEGMENT_TREE_MAXN
#define SEGMENT_TREE_MAXN 200100
#define NODE_VAL_TYPE ll
#endif
struct SegmentNode{
	int be, en;
	NODE_VAL_TYPE minv, add;
};
struct SegmentTree{
	int l;
	SegmentNode tree[SEGMENT_TREE_MAXN * 4];

	inline int GetLeft(int no) {return no << 1;}
	inline int GetRight(int no) {return (no << 1) + 1;}
	inline int GetFa(int no) {return no >> 1;}
	inline SegmentTree(){ l = 0; }

	void Build(int no, int l, int r, NODE_VAL_TYPE orig = 0, NODE_VAL_TYPE *a = NULL){
		if(l > r) r = l;
		if(l == r){
			tree[no].be = tree[no].en = l;
			tree[no].add = 0;
			if(a == NULL) tree[no].minv = orig;
			else tree[no].minv = a[l];
			tree[no].add = 0;
			return;
		}
		tree[no].be = l; tree[no].en = r;
		int mid = (l + r) / 2;
		Build(GetLeft(no), l, mid, orig, a);
		Build(GetRight(no), mid + 1, r, orig, a);
		tree[no].add = 0;
		PushUp(no);
	}
	inline void PushUp(int no) {

		tree[no].minv = min1(tree[GetLeft(no)].minv, tree[GetRight(no)].minv);
	}
	inline void PushDown(int no) {
		int le = GetLeft(no), ri = GetRight(no);
		tree[le].add += tree[no].add;
		tree[le].minv += tree[no].add;
		tree[ri].add += tree[no].add;
		tree[ri].minv += tree[no].add;
		tree[no].add = 0;
	}
	void Upd(int l, int r, int no, NODE_VAL_TYPE ranadd){
		if(l <= tree[no].be && r >= tree[no].en){
			tree[no].add += ranadd;
			tree[no].minv += ranadd;
			return;
		}
		if(tree[no].add && tree[no].be != tree[no].en) PushDown(no);
		int mid = (tree[no].be + tree[no].en) >> 1;
		if(r >= tree[no].be && l <= mid) Upd(l, r, GetLeft(no), ranadd);
		if(r >= mid + 1 && l <= tree[no].en) Upd(l, r, GetRight(no), ranadd);
		PushUp(no);
	}
	void UpdTo(int loc, int no, NODE_VAL_TYPE ranadd){
		if(loc <= tree[no].be && loc >= tree[no].en){
			tree[no].add = 0;
			tree[no].minv = ranadd;
			return;
		}
		if(tree[no].add && tree[no].be != tree[no].en) PushDown(no);
		int mid = (tree[no].be + tree[no].en) >> 1;
		if(loc <= mid) UpdTo(loc, GetLeft(no), ranadd);
		else UpdTo(loc, GetRight(no), ranadd);
		PushUp(no);
	}
	NODE_VAL_TYPE GetMinv(int l, int r, int no){
		if(l > r) return 0;
		if(l <= tree[no].be && r >= tree[no].en)
			return tree[no].minv;
		if(tree[no].add && tree[no].be != tree[no].en) PushDown(no);
		NODE_VAL_TYPE ans = MOD;
		int mid = (tree[no].be + tree[no].en) >> 1;
		if(r >= tree[no].be && l <= mid) ans = min(ans, GetMinv(l, r, GetLeft(no)));
		if(r >= mid + 1 && l <= tree[no].en) ans = min(ans, GetMinv(l, r, GetRight(no)));
		return ans;
	}
} sgt[2];

const int maxn = SEGMENT_TREE_MAXN;
int n;
pii orig[maxn];


int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
#endif //...........................................................................................................

	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &orig[i].first, &orig[i].second);
		orig[i].first--; orig[i].second--;
		if (max(orig[i].first, orig[i].second) < n || min(orig[i].first, orig[i].second) >= n) {
			puts("-1");
			return 0;
		}
	}
	for (int i = 0; i < 2; i++) {
		sgt[i].Build(1, 0, n + 1, n + 1);
		sgt[i].UpdTo(n, 1, 0);
	}
	sort(orig, orig + n, [](const pii& a, const pii& b){
		return min(a.first, a.second) < min(b.first, b.second);
	});
#ifdef DEBUG
	for (int i = 0; i < n; i++) {
		cerr << max(orig[i].first, orig[i].second) - n << '|' << int(orig[i].first > orig[i].second) << ' ';
	}
	cerr << endl;
	cerr << endl;

#endif
#ifdef DEBUG
		for (int i = 0; i <= n; i++) {
			cerr << sgt[0].GetMinv(i, i, 1) << ' ';
		}
		cerr << endl;
		for (int i = 0; i <= n; i++) {
					cerr << sgt[1].GetMinv(i, i, 1) << ' ';
				}
				cerr << endl;
				cerr << endl;
#endif
	for (int i = 0, last = n; i < n; i++) {
		int flipped = orig[i].first > orig[i].second;
		int big = max(orig[i].first, orig[i].second) - n;
		int upd[2] = {MOD, MOD}, no_upd[2] = {MOD, MOD};
		for (int cate = 0; cate < 2; cate++) {
			upd[cate] = sgt[1 - cate].GetMinv(big + 1, n, 1) + (flipped != cate);
		}
		if (big < last) {
			for (int cate = 0; cate < 2; cate++) {
				no_upd[cate] = (flipped != cate);
			}
		}

		if (big > last) {
			for (int cate = 0; cate < 2; cate++) {
				sgt[cate].Upd(0, n, 1, n + 1);
			}
 		} else {
 			for (int cate = 0; cate < 2; cate++) {
 				sgt[cate].Upd(0, n, 1, no_upd[cate]);
 			}
 		}
		for (int cate = 0; cate < 2; cate++) {
			sgt[cate].UpdTo(last, 1, upd[cate]);
		}

#ifdef DEBUG
		for (int i = 0; i <= n; i++) {
			cerr << sgt[0].GetMinv(i, i, 1) << ' ';
		}
		cerr << endl;
		for (int i = 0; i <= n; i++) {
					cerr << sgt[1].GetMinv(i, i, 1) << ' ';
				}
				cerr << endl;
				cerr << endl;
#endif
		last = big;
	}
	ll ans = min(sgt[0].GetMinv(0, n, 1), sgt[1].GetMinv(0, n, 1));
	if (ans > n) puts("-1");
	else printf("%I64d\n", ans);


	return 0;
}
