#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
struct dsu {
int lab[N];
dsu() {
memset(lab, -1, sizeof(lab));
}
int find(int u) {
return lab[u] < 0 ? u : lab[u] = find(lab[u]);
}
bool merge(int u, int v) {
if ((u = find(u)) == (v = find(v))) {
return false;
}
if (lab[u] > lab[v]) {
swap(u, v);
}
lab[u] += lab[v];
lab[v] = u;
return true;
}
};
dsu g;
int n, m;
vector<int> adj[N];
vector<int> node;
int d[N];
int c(int x) {
return lower_bound(node.begin(), node.end(), x) - node.begin() + 1;
}
void bfs(int u) {
queue<int> q;
q.push(u);
d[u] = 0;
while (!q.empty()) {
int v = q.front();
q.pop();
for (int x : adj[v]) {
if (d[x] == -1) {
d[x] = d[v] + 1;
q.push(x);
} else if ((d[x] & 1) == (d[v] & 1)) {
cout << "No";
exit(0);
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
memset(d, -1, sizeof(d));
cin >> n >> m;
vector<pair<int, int> > sus;
for (int i = 1; i <= m; i++) {
int a, b, c;
cin >> a >> b >> c;
if (c == 1) {
g.merge(a, b);
} else {
sus.emplace_back(a, b);
}
}
for (int i = 1; i <= n; i++) {
node.emplace_back(g.find(i));
}
sort(node.begin(), node.end());
node.erase(unique(node.begin(), node.end()), node.end());
int nn = node.size();
for (auto x : sus) {
if (g.find(x.first) == g.find(x.second)) {
cout << "No" << '\n';
return 0;
}
adj[c(g.find(x.first))].emplace_back(c(g.find(x.second)));
adj[c(g.find(x.second))].emplace_back(c(g.find(x.first)));
}
for (int i = 1; i <= nn; i++) {
if (d[i] == -1) {
bfs(i);
}
}
cout << "Yes" << '\n';
return 0;
}