#include <bits/stdc++.h>
using namespace std;
void input() {}
template <typename... R>
void input(int& f, R&... r) {
  scanf("%d", &f);
  input(r...);
}
template <typename... R>
void input(double& f, R&... r) {
  scanf("%lf", &f);
  input(r...);
}
template <typename... R>
void input(long long& f, R&... r) {
  scanf("%lld", &f);
  input(r...);
}
template <typename... R>
void input(char& f, R&... r) {
  scanf("%c", &f);
  input(r...);
}
template <typename T, typename... R>
void input(vector<T>& f, R&... r) {
  for (int i = 0; i < (int)(f.size()); i++) input(f[i]);
  input(r...);
}
class UnionFind {
 private:
  vector<int> par;
  vector<int> dist;

 public:
  UnionFind(int n) {
    par.resize(n, -1);
    dist.resize(n, 0);
  }
  int distpar(int x) {
    if (par[x] < 0) return 0;
    return dist[x] += distpar(par[x]);
  }
  int root(int x) {
    if (par[x] < 0) return x;
    distpar(x);
    return par[x] = root(par[x]);
  }
  bool unite(int x, int y, int d) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) {
      return d + distpar(y) == distpar(x);
    }
    par[rx] += par[ry];
    dist[ry] = distpar(x) - distpar(y) - d;
    par[ry] = rx;
    return true;
  }
  bool same(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
  int size(int x) { return -par[root(x)]; }
  void print() {
    cout << "par : ";
    for (int i = 0; i < (int)(par.size()); i++) {
      cout << i << "->" << par[i] << " ";
    }
    cout << endl;
    cout << "dist : ";
    for (int i = 0; i < (int)(par.size()); i++) {
      cout << i << "->" << dist[i] << " ";
    }
  }
};
int main() {
  int N, M;
  input(N, M);
  UnionFind uni(N);
  for (int i = 0; i < (int)(M); i++) {
    int l, r, d;
    input(l, r, d);
    l--;
    r--;
    if (!uni.unite(l, r, d)) {
      puts("No");
      return 0;
    }
  }
  puts("Yes");
  getchar();
  getchar();
}
