#include <bits/stdc++.h>
using namespace std;
struct union_find_tree {
  std::vector<int> par, rank;
  union_find_tree() {}
  union_find_tree(int size) {
    par = std::vector<int>(size);
    rank = std::vector<int>(size);
    for (int i = 0; i < size; ++i) par[i] = i;
  }
  int root(int x) {
    if (x == par[x]) return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y]) ++rank[x];
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
};
vector<pair<int, int>> c[100010];
bool dfs(map<int, long>& x, int v, int p) {
  bool res = true;
  for (auto& e : c[v]) {
    int u = e.first;
    int d = e.second;
    if (u == p) continue;
    if (x.count(u)) return x[u] == x[v] + d;
    x[u] = x[v] + d;
    res = res && dfs(x, u, v);
  }
  return res;
}
int main() {
  int n, m;
  cin >> n >> m;
  union_find_tree t(n);
  for (int i = 0; i < m; ++i) {
    int l, r, d;
    cin >> l >> r >> d;
    --l, --r;
    c[l].emplace_back(r, d);
    c[r].emplace_back(l, -d);
    t.unite(l, r);
  }
  map<int, vector<int>> g;
  for (int i = 0; i < n; ++i) g[t.root(i)].push_back(i);
  bool res = true;
  for (auto& e : g) {
    map<int, long> x;
    auto& a = e.second;
    x[a[0]] = 0;
    res = res && dfs(x, a[0], -1);
  }
  cout << (res ? "Yes" : "No") << endl;
}
