#include #include #include #include #include #include #include #include #include #include #define mkp make_pair #define mkt make_tuple #define rep(i, n) for (int i = 0; i < (n); ++i) #define all(v) v.begin(), v.end() using namespace std; typedef long long ll; const ll MOD = 1e9 + 7; // const ll MOD = 998244353; template void chmin(T &a, const T &b) { if (a > b) a = b; } template void chmax(T &a, const T &b) { if (a < b) a = b; } class DisjointSet { public: int N; vector rank, p; vector sz; DisjointSet() {} DisjointSet(int n) : N(n), rank(n), p(n), sz(n) { for (int i = 0; i < N; i++) makeSet(i); } void makeSet(int x) { p[x] = x; rank[x] = 0; sz[x] = 1; } bool same(int x, int y) { return leader(x) == leader(y); } void unite(int x, int y) { if (same(x, y)) return; link(leader(x), leader(y)); } void link(int x, int y) { if (rank[x] > rank[y]) swap(x, y); p[x] = y; sz[y] += sz[x]; if (rank[x] == rank[y]) { ++rank[y]; } } int leader(int x) { if (x != p[x]) p[x] = leader(p[x]); return p[x]; } int size(int x) { return sz[leader(x)]; } }; const int MAX = 2e5 + 10; void solve() { int N; cin >> N; vector H(N), W(N); rep(i, N) cin >> H[i] >> W[i]; { DisjointSet us(MAX); rep(i, N) us.unite(H[i], W[i]); int leader = us.leader(H[0]); rep(i, N) if (leader != us.leader(H[i])) { cout << 0 << endl; return; } } vector in(MAX, 0), out(MAX, 0); rep(i, N) { in[W[i]]++; out[H[i]]++; } int s = -1, t = -1; for (int k = 0; k < MAX; k++) { if (in[k] - out[k] == 0) continue; if (in[k] - out[k] == 1) { if (t != -1) { cout << 0 << endl; return; } t = k; } else if (in[k] - out[k] == -1) { if (s != -1) { cout << 0 << endl; return; } s = k; } else { cout << 0 << endl; return; } } if (s == -1 && t == -1) { int cnt = 0; rep(k, MAX) if (in[k] > 0) cnt++; cout << cnt << endl; } else if (s == -1 || t == -1) { cout << 0 << endl; } else { cout << 1 << endl; } } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); solve(); return 0; }