#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
struct Edge {
  int pre, post, weight;
  bool operator<(const Edge& o) const { return weight < o.weight; }
};
class UnionFind {
 private:
  vector<int> par;
  vector<int> rank;
  vector<int> diff_weight;

 public:
  UnionFind(int N) : par(N), rank(N), diff_weight(N) {
    for (int i = 0; i < N; i++) {
      this->par[i] = i;
      this->rank[i] = 0;
      this->diff_weight[i] = 0;
    }
  };
  ~UnionFind(){};
  int root(int x) {
    if (x == this->par[x])
      return x;
    else {
      this->diff_weight[x] += this->diff_weight[par[x]];
      return root(this->par[x]);
    }
  };
  int weight(int x) {
    this->root(x);
    return this->diff_weight[x];
  }
  void unite(int x_ch, int y_ch, int w) {
    w += this->weight(x_ch);
    w -= this->weight(y_ch);
    int x = this->root(x_ch);
    int y = this->root(y_ch);
    if (x != y) {
      if (this->rank[x] < this->rank[y]) {
        swap(x, y);
        w = -w;
      }
      if (this->rank[x] == this->rank[y]) this->rank[x]++;
      this->par[y] = x;
      this->diff_weight[y] = w;
    }
  };
  int diff(int x, int y) { return this->weight(y) - this->weight(x); }
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<int> L(M), R(M), D(M);
  for (int i = 0; i < M; i++) cin >> L[i] >> R[i] >> D[i];
  transform(L.begin(), L.end(), L.begin(), [](int i) { return i - 1; });
  transform(R.begin(), R.end(), R.begin(), [](int i) { return i - 1; });
  UnionFind tree(N);
  vector<Edge> edge_arr;
  for (int i = 0; i < M; i++) {
    Edge tmp{L[i], R[i], D[i]};
    edge_arr.push_back(tmp);
  }
  for (int i = 0; i < M; i++) {
    int pre = edge_arr[i].pre;
    int post = edge_arr[i].post;
    if (tree.root(pre) == tree.root(post)) {
      int diff = tree.diff(pre, post);
      if (diff != edge_arr[i].weight) {
        cout << "No" << endl;
        return 0;
      }
    } else
      tree.unite(pre, post, edge_arr[i].weight);
  }
  cout << "Yes" << endl;
}
