#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using namespace std;
template <class T>
void vin(vector<T>& v, int n) {
  v.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> v[i];
  }
}
struct UnionFind {
  static const int MAX = 1000001;
  int par[MAX];
  void init(int N) {
    for (int i = 0; i < N; ++i) {
      par[i] = -1;
    }
  }
  void init() {
    for (int i = 0; i < MAX; ++i) {
      par[i] = -1;
    }
  }
  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (par[x] > par[y]) {
      int tmp = x;
      x = y;
      y = tmp;
    }
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -par[find(x)]; }
};
int N, M;
struct E {
  int l, r, d;
};
vector<E> s;
bool used[101010];
int dist[101010];
int main() {
  cin >> N >> M;
  bool ok = true;
  for (int(i) = (0); (i) < (int)(M); ++(i)) {
    int l, r, d;
    cin >> l >> r >> d;
    s.push_back({l, r, d});
  }
  sort(s.begin(), s.end(), [](const E& a, const E& b) {
    if (a.l == b.l) {
      return a.r < b.r;
    } else {
      return a.l < b.l;
    }
  });
  for (int(i) = (0); (i) < (int)(M); ++(i)) {
    E e = s[i];
    int l = e.l, r = e.r, d = e.d;
    if (!used[l] and !used[r]) {
      dist[l] = -d;
      dist[r] = 0;
      used[l] = true;
      used[r] = true;
    } else if (used[l] and !used[r]) {
      dist[r] = dist[l] + e.d;
      used[r] = true;
    } else if (used[r] and !used[l]) {
      dist[l] = dist[r] - e.d;
      used[l] = true;
    } else {
      if (dist[r] - dist[l] != e.d) {
        ok = false;
      }
    }
  }
  cout << (ok ? "Yes" : "No") << endl;
}
