#include <bits/stdc++.h>
using namespace std;
using LL = long long;
struct edge {
  int to;
  long long cost;
  edge(int to_, long long cost_) : to(to_), cost(cost_) {}
};
int N, M;
vector<edge> graph[123456];
int color[123456];
void dfs(int i, int col) {
  if (color[i] >= 0) {
    return;
  }
  color[i] = col;
}
vector<int> L, R, D;
LL dist[123456];
bool flag[123456];
void dfs2(int v, int dis) {
  if (flag[v]) return;
  flag[v] = true;
  dist[v] = dis;
  for (auto e : graph[v]) {
    dfs2(e.to, dis + e.cost);
  }
}
int main(void) {
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int l, r, d;
    cin >> l >> r >> d;
    --r;
    --l;
    graph[l].push_back({r, d});
    graph[r].push_back({l, -d});
    L.push_back(l);
    R.push_back(r);
    D.push_back(d);
  }
  fill(color, color + N, -1);
  for (int i = 0; i < N; ++i) {
    dfs(i, i);
  }
  set<int> cs;
  vector<int> tsuna;
  for (int i = 0; i < N; ++i) {
    if (!cs.count(color[i])) {
      tsuna.push_back(i);
    }
    cs.insert(color[i]);
  }
  for (int i = 1; i < tsuna.size(); ++i) {
    int l = tsuna[i - 1], r = tsuna[i];
    graph[l].push_back({r, 0});
    graph[r].push_back({l, 0});
    L.push_back(l);
    R.push_back(r);
    D.push_back(0);
  }
  dfs2(0, 0);
  for (int i = 0; i < M; ++i) {
    if (dist[L[i]] + D[i] != dist[R[i]]) {
      cout << "No\n";
      return 0;
    }
  }
  cout << "Yes\n";
  return 0;
}
