#include #include #include #include struct DSU { std::vector uf; std::vector data; DSU(int32_t n): uf(n, -1), data(n, 0) {} int32_t find(int32_t u) { return uf[u] < 0 ? u : (uf[u] = find(uf[u])); } bool merge(int32_t u, int32_t v) { u = find(u); v = find(v); ++data[u]; if (u == v) return false; if (uf[u] > uf[v]) { std::swap(u, v); } data[u] += std::exchange(data[v], 0); uf[u] += std::exchange(uf[v], u); return true; } int32_t getSize(int32_t u) { return -uf[find(u)]; } int32_t countEdges(int32_t u) { return data[find(u)]; } }; int main() { int32_t n, m, k; std::cin >> n >> m >> k; DSU dsu(n); for (int32_t i = 0; i < m; ++i) { int32_t u, v; std::cin >> u >> v; --u; --v; dsu.merge(u, v); } int64_t edgeCount = k * (k - 1); int32_t ans = 0; for (int32_t u = 0; u < n; ++u) { ans += dsu.find(u) == u && dsu.getSize(u) == k && dsu.countEdges(u) == edgeCount; } std::cout << ans << '\n'; return 0; }