#include #define all(vec) vec.begin(), vec.end() #define pb push_back #define eb emplace_back using namespace std; using ll = long long; using P = pair; using V = vector; using VL = vector; constexpr ll INF = (1LL << 30) - 1LL; constexpr ll MOD = 1e9 + 7; constexpr int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; template void chmin(T &a, T b) { a = min(a, b); } template void chmax(T &a, T b) { a = max(a, b); } void ok() { cerr << "ok" << endl; } struct UnionFind { vector par, sz; UnionFind(int n) { par.resize(n); sz.resize(n, 1); iota(all(par), 0); } inline int find(int x) { if (x == par[x]) return x; return par[x] = find(par[x]); } void unite(int u, int v) { u = find(u), v = find(v); if (u == v) return; if (sz[u] < sz[v]) swap(u, v); par[v] = u; sz[u] += sz[v]; } inline bool same(int u, int v) { return find(u) == find(v); } }; vector> G; struct SCC { int n; vector ord, vis, cm; vector> bl, rG; SCC(int n) : n(n), bl(n), rG(n), cm(n), vis(n) {} void dfs(int i) { vis[i] = 1; for (auto &e : G[i]) { if (vis[e]) continue; dfs(e); } ord.eb(i); } void rdfs(int i, int c) { vis[i] = 1; bl[c].eb(i); cm[i] = c; for (auto &e : rG[i]) { if (vis[e]) continue; rdfs(e, c); } } void build() { for (int i = 0; i < n; i++) { for (auto &e : G[i]) { rG[e].eb(i); } } for (int i = 0; i < n; i++) { if (!vis[i]) dfs(i); } reverse(all(ord)); vis.assign(n, 0); int k = 0; for (auto &e : ord) { if (!vis[e]) { bl.eb(vector()); rdfs(e, k); k++; } } } }; int main() { cin.tie(0); ios::sync_with_stdio(0); int n, m; cin >> n >> m; UnionFind uf(n); V a(m), b(m), c(m); G.resize(n); for (int i = 0; i < m; i++) { cin >> a[i] >> b[i] >> c[i]; --a[i]; --b[i]; if (c[i] == 1) { if (uf.same(a[i], b[i])) { cout << "Yes\n"; return 0; } uf.unite(a[i], b[i]); } } for (int i = 0; i < m; i++) { if (c[i] == 2) { if (uf.same(a[i], b[i])) { cout << "Yes\n"; return 0; } G[uf.find(a[i])].eb(uf.find(b[i])); } } SCC scc(n); scc.build(); for (int i = 0; i < n; i++) { if (scc.bl[i].size() > 1) { cout << "Yes\n"; return 0; } } cout << "No\n"; return 0; }