// goodwincommaderek@gmail.com import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashSet; public class ordinary_dg_ac implements Runnable { // important observation: // we're looking for independent cliques of size k public static void main(String[] args) { new Thread(null, new ordinary_dg_ac(), "", 1<<27).start(); } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] in; int $; in = br.readLine().split(" "); $=0; int N = Integer.parseInt(in[$++]); int M = Integer.parseInt(in[$++]); int K = Integer.parseInt(in[$++]); Graph g = new Graph(N); for(int m=0;m 2) { M = Integer.MAX_VALUE; continue; } if (in.length < 2) break; int a = Integer.parseInt(in[$++]); int b = Integer.parseInt(in[$++]); if (a == b) { System.out.println("bad data"); } else { // i use treesets for edges, so duplicate edges are not a thing i worry about g.connect(a-1,b-1); } } int ans = solve(g, K); System.out.println(ans); } catch (IOException ioe) { System.err.println("NOOOOOOO-"); } } static int solve(Graph g, int K) { // it must be its own, separate component ConnectivityCheckInEitherDirection cgied = new ConnectivityCheckInEitherDirection(g); ArrayDeque> setsThatWork = new ArrayDeque<>(); // it needs to be of size K for (ArrayList set : cgied.connectedSets) { if (set.size() == K) { setsThatWork.addLast(set); } } // it needs to be a clique for(int i = setsThatWork.size(); i > 0; i--) { ArrayList set = setsThatWork.pollFirst(); boolean fail = false; for (Integer uo : set) { int u = uo.intValue(); if (g.nexts[u].size() != K-1) { fail = true; break; } } if (!fail) { setsThatWork.addLast(set); } } // and that's your answer. return setsThatWork.size(); } static class ConnectivityCheckInEitherDirection { Graph g; ArrayList> connectedSets; boolean[] visited; ConnectivityCheckInEitherDirection(Graph g) { this.g = g; connectedSets = new ArrayList<>(); visited = new boolean[g.N]; go(); } ArrayList connectedSet; void go() { for (int n=0; n(); dfs(n); connectedSets.add(connectedSet); } } } void dfs(int u) { visited[u] = true; connectedSet.add(u); for(Integer vo : g.nexts[u]) { int v = vo.intValue(); if (!visited[v]) { dfs(v); } } for(Integer vo : g.prevs[u]) { int v = vo.intValue(); if (!visited[v]) { dfs(v); } } } } static class Graph { int N; HashSet[] nexts, prevs; Graph(int N) { this.N = N; nexts = new HashSet[N]; prevs = new HashSet[N]; for(int n=0; n(); for(int n=0; n(); } void connect(int a, int b) { nexts[a].add(b); prevs[b].add(a); } } }