#include using namespace std; using int64 = long long; const int INF = 1 << 30; struct UnionFind { vector< int > data; UnionFind(int sz) { data.assign(sz, -1); } bool unite(int x, int y) { x = find(x), y = find(y); if(x == y) return (false); if(data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; return (true); } int find(int k) { if(data[k] < 0) return (k); return (data[k] = find(data[k])); } int size(int k) { return (-data[find(k)]); } }; int main() { int N, A[100000], B[100000]; int64 in[100001] = {}, out[100001] = {}; UnionFind uf(100001); cin >> N; int low = INF; for(int i = 0; i < N; i++) { cin >> A[i] >> B[i]; out[A[i]]++; in[B[i]]++; low = min(low, B[i]); uf.unite(A[i], B[i]); } int64 up[100002] = {}, down[100002] = {}; //i-1 ↔ i for(int i = 100000; i > low; i--) { up[i] = max((up[i + 1] + out[i]) - (down[i + 1] + in[i]), 0LL); down[i] = max((down[i + 1] + in[i]) - (up[i + 1] + out[i]), 0LL); if(up[i] > 0 || down[i] > 0) uf.unite(i - 1, i); } for(int i = 100000; i > low; i--) { if(uf.find(i) != uf.find(i - 1)) { uf.unite(i, i - 1); assert(up[i] == 0 && down[i] == 0); up[i] = down[i] = 1; } } auto check = [&](int left) { for(int i = left; i <= 100000; i++) up[i]--; UnionFind uf2(100001); for(int i = 0; i < N; i++) uf2.unite(A[i], B[i]); for(int i = 100000; i > low; i--) { if(up[i] > 0 || down[i] > 0) uf2.unite(i - 1, i); } int par = uf2.find(100000); bool f = true; for(int i = 0; i < N; i++) f &= uf2.find(A[i]) == par; for(int i = left; i <= 100000; i++) up[i]++; return f; }; int ok = 100001, ng = low; while(ok - ng > 1) { int mid = (ok + ng) / 2; if(check(mid)) ok = mid; else ng = mid; } int64 all = 0; for(int i = ok; i <= 100000; i++) up[i]--; for(int i = 0; i <= 100000; i++) all += up[i]; cout << all << endl; }