#include #include #include #include #include #include #include struct Point { size_t x; size_t y; bool visited = false; friend bool operator <(const Point&a, const Point&b) { if (a.x == b.x) return a.y < b.y; return a.x < b.x; } }; int main() { size_t num = 0; std::cin >> num; std::vector> nodes; std::unordered_map>> xneigh; std::unordered_map>> yneigh; for (size_t i = 0; i < num; i++) { std::shared_ptr p = std::make_shared(); std::cin >> p->x >> p->y; nodes.push_back(p); xneigh[p->x].push_back(p); yneigh[p->y].emplace_back(std::move(p)); } std::queue> to_visit; size_t total_count = 0; for (const auto& elem : nodes) { if (elem->visited) continue; total_count += 1; to_visit.push(elem); elem->visited = true; while (!to_visit.empty()) { auto node = to_visit.front(); to_visit.pop(); for (const auto &neigh : xneigh[node->x]) { if (neigh->y != node->y && !neigh->visited) { to_visit.push(neigh); } neigh->visited = true; } for (const auto &neigh : yneigh[node->y]) { if (neigh->x != node->x && !neigh->visited) { to_visit.push(neigh); } neigh->visited = true; } } } std::cout << total_count - 1 << std::endl; }