#include using namespace std; using ll = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, M; long long K; cin >> N >> M >> K; vector> g(N), rg(N); vector> edges; edges.reserve(M); for (int i = 0; i < M; i++) { int u, v; cin >> u >> v; --u; --v; g[u].push_back(v); rg[v].push_back(u); edges.push_back({u, v}); } // Kosaraju vector used(N, 0), order; order.reserve(N); for (int s = 0; s < N; s++) { if (used[s]) continue; stack> st; st.push({s, 0}); used[s] = 1; while (!st.empty()) { auto &[v, idx] = st.top(); if (idx < (int)g[v].size()) { int to = g[v][idx++]; if (!used[to]) { used[to] = 1; st.push({to, 0}); } } else { order.push_back(v); st.pop(); } } } vector comp(N, -1); vector> members; int C = 0; for (int i = N - 1; i >= 0; i--) { int s = order[i]; if (comp[s] != -1) continue; members.push_back({}); stack st; st.push(s); comp[s] = C; while (!st.empty()) { int v = st.top(); st.pop(); members[C].push_back(v); for (int to : rg[v]) { if (comp[to] == -1) { comp[to] = C; st.push(to); } } } C++; } vector sz(C, 0); for (int c = 0; c < C; c++) sz[c] = (int)members[c].size(); vector> dag(C); vector>> inner_edges(C); vector> in_adj(N); for (auto [u, v] : edges) { int cu = comp[u], cv = comp[v]; if (cu == cv) { inner_edges[cu].push_back({u, v}); in_adj[u].push_back(v); } else { dag[cu].push_back(cv); } } for (int c = 0; c < C; c++) { sort(dag[c].begin(), dag[c].end()); dag[c].erase(unique(dag[c].begin(), dag[c].end()), dag[c].end()); } // type: // 0 = bad // 1 = singleton // 2 = odd-period nontrivial SCC vector type(C, 0); vector seen(N, 0); vector dist(N, 0); for (int c = 0; c < C; c++) { if (sz[c] == 1) { type[c] = 1; // singleton continue; } int root = members[c][0]; stack st; st.push(root); seen[root] = 1; dist[root] = 0; while (!st.empty()) { int v = st.top(); st.pop(); for (int to : in_adj[v]) { if (!seen[to]) { seen[to] = 1; dist[to] = dist[v] + 1; st.push(to); } } } ll gg = 0; for (auto [u, v] : inner_edges[c]) { ll x = dist[u] + 1 - dist[v]; if (x < 0) x = -x; gg = std::gcd(gg, x); } for (int v : members[c]) seen[v] = 0; if (gg % 2 == 1) type[c] = 2; // good nontrivial SCC else type[c] = 0; // impossible SCC } for (int c = 0; c < C; c++) { if (type[c] == 0) { cout << "No\n"; return 0; } } int start = comp[0]; if (type[start] != 2) { // start SCC must be good nontrivial cout << "No\n"; return 0; } // Topological order vector indeg(C, 0); for (int c = 0; c < C; c++) { for (int to : dag[c]) indeg[to]++; } queue q; for (int c = 0; c < C; c++) { if (indeg[c] == 0) q.push(c); } vector topo; topo.reserve(C); while (!q.empty()) { int v = q.front(); q.pop(); topo.push_back(v); for (int to : dag[v]) { if (--indeg[to] == 0) q.push(to); } } // longest path from start, also restore one such path const int NEG = -1e9; vector dp(C, NEG), prv(C, -1); dp[start] = 1; for (int v : topo) { if (dp[v] < 0) continue; for (int to : dag[v]) { if (dp[to] < dp[v] + 1) { dp[to] = dp[v] + 1; prv[to] = v; } } } int end = -1, best = -1; for (int c = 0; c < C; c++) { if (dp[c] > best) { best = dp[c]; end = c; } } if (best != C) { cout << "No\n"; return 0; } vector path; for (int cur = end; cur != -1; cur = prv[cur]) path.push_back(cur); reverse(path.begin(), path.end()); // singleton SCC must not be consecutive for (int i = 0; i + 1 < C; i++) { if (type[path[i]] == 1 && type[path[i + 1]] == 1) { cout << "No\n"; return 0; } } cout << "Yes\n"; return 0; }