#include using namespace std; #define int long long template ostream& operator<<(ostream& os, const vector& v) { os << '['; for(int i = 0; i < v.size(); i++) { if(i) os << ", "; os << v[i]; } os << ']'; return os; } void solve() { int n; cin >> n; map> x2ys; // mapa x => vektor y souradnic bodu v tom xu map> y2xs; for(int i = 0; i < n; i++) { int x, y; cin >> x >> y; x2ys[x].push_back(y); y2xs[y].push_back(x); } // for(auto& [key, _] : x2ys) // cout << key << ": " << x2ys[key] << endl; // cout << endl; // for(auto& [key, _] : y2xs) // cout << key << ": " << y2xs[key] << endl; // y2xs.erase(3); // cout << endl; // for(auto& [key, _] : y2xs) // cout << key << ": " << y2xs[key] << endl; int noc = 0; // num of ocmponents while(!x2ys.empty() || !y2xs.empty()) { noc++; vector x_todo; vector y_todo; if(!x2ys.empty()) { auto it = x2ys.begin(); for(int y : it->second) y_todo.push_back(y); x2ys.erase(it->first); } else if(!y2xs.empty()) { auto it = y2xs.begin(); for(int x : it->second) x_todo.push_back(x); y2xs.erase(it->first); } while(!x_todo.empty() || !y_todo.empty()) { for(int x : x_todo) { auto it = x2ys.find(x); if(it == x2ys.end()) continue; for(int y : it->second) y_todo.push_back(y); x2ys.erase(it); } x_todo = {}; for(int y : y_todo) { auto it = y2xs.find(y); if(it == y2xs.end()) continue; for(int x : it->second) x_todo.push_back(x); y2xs.erase(it); } y_todo = {}; // cout << "x_todo: " << x_todo << endl; // cout << "y_todo: " << y_todo << endl; // cout << endl; } //yka = x2ys. } // cout << "noc: " << noc << endl; cout << (noc - 1) << endl; } int32_t main() { ios::sync_with_stdio(false); cin.tie(0); solve(); return 0; }