#include using namespace std; //高速化 struct ponjuice{ponjuice(){cin.tie(0);ios::sync_with_stdio(0);cout<using vc = vector; templateusing vvc = vc>; templateusing vvvc = vvc>; using vi = vc; using vvi = vvc; using vvvi = vvvc; using vl = vc; using vvl = vvc; using vvvl = vvvc; using pi = pair; using pl = pair; using ull = unsigned ll; templateusing priq = priority_queue; templateusing priqg = priority_queue, greater>; // for文 #define overload4(a, b, c, d, e, ...) e #define rep1(n) for(ll i = 0; i < n; i++) #define rep2(i, n) for(ll i = 0; i < n; i++) #define rep3(i, a, b) for(ll i = a; i < b; i++) #define rep4(i, a, b, step) for(ll i = a; i < b; i+= step) #define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__) #define per1(n) for(ll i = n-1; i >= 0; i--) #define per2(i, n) for(ll i = n-1; i >= 0; i--) #define per3(i, a, b) for(ll i = b-1; i >= a; i--) #define per4(i, a, b, step) for(ll i = b-1; i >= a; i-= step) #define per(...) overload4(__VA_ARGS__, per4, per3, per2, per1)(__VA_ARGS__) //関数 #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define si(x) (ll)(x).size() templateinline bool chmax(S& a, T b){return a < b && ( a = b , true);} templateinline bool chmin(S& a, T b){return a > b && ( a = b , true);} inline void yes(){cout << "Yes\n";} inline void no(){cout << "No\n";} inline void yesno(bool y = true){if(y)yes();else no();} //定数 constexpr ll mod = 998244353; constexpr ll minf=-(1<<29); constexpr ll inf=(1<<29); constexpr ll MINF=-(1LL<<60); constexpr ll INF=(1LL<<60); const int dx[4] ={-1, 0, 1, 0}; const int dy[4] ={ 0, 1, 0,-1}; const int dx8[8] ={-1,-1,-1, 0, 1, 1, 1, 0}; const int dy8[8] ={-1, 0, 1, 1, 1, 0,-1,-1}; void solve(); int main() { int t = 1; // cin >>t; while(t--){ solve(); } } /* せっかくなので、PPC は全てコメント書きます OR なので、かなり楽そう? とりあえず,SCCをしてグラフを見る 一つ前のやつから自分に来れないのであれば確実に不可能 強連結成分が2部グラフ(無向グラフとしてみた時) のとき、mod2が01が確定してしまうので、これはNG 連結成分が一つのものがある時、それが連続するとNG ぐらいかなぁ k使ってないのちょっと不安だけど とりあえず書いてみて出すか なんかREでてる */ #include using namespace atcoder; void solve(){ int n,m,k; cin >> n >> m >> k; scc_graph g(n); vector> graph(n); rep(i,0,m) { int u,v; cin >> u >> v; u--,v--; graph[u].push_back(v); g.add_edge(u,v); } auto res = g.scc(); vector num(n); rep(i,0,res.size()) { for(auto c: res[i]) { num[c] = i; } if(i!=0 && res[i-1].size() == 1 && res[i].size() == 1) { no(); return; } } vector none(res.size()-1, 1); rep(i,0,n){ for(auto to: graph[i]) { if(num[i] +1 == num[to]) { none[num[i]] = 0; } } } if(accumulate(all(none), 0)) { no(); return; } vector od(n,-1); auto check = [&,graph](const vector& v) -> bool { set in(all(v)); bool ok = false; auto dfs = [&](auto&& self, int nw) -> void { for(auto to: graph[nw]) { if(in.count(to) == 0) continue; if(od[to] == -1) { od[to] = od[nw]^1; self(self, to); }else { if(od[to] == od[nw]) ok = true; } } }; od[v[0]] = 0; dfs(dfs, v[0]); return ok; }; rep(i,0,res.size()) { if(res[i].size() != 1) { if(!check(res[i])) { no(); return; } } } yes(); return; }