#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (auto x : v) os << x << " ";
  return os << "\n";
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int N, M;
  cin >> N >> M;
  vector<vector<pair<int, int>>> adj(N);
  vector<int> indegree(N), outdegree(N);
  for (int i = 0; i < (M); ++i) {
    int L, R, D;
    cin >> L >> R >> D;
    adj[R - 1].push_back({L - 1, D});
    indegree[L - 1]++;
    outdegree[R - 1]++;
  }
  vector<int> dist(N, -1);
  for (int i = 0; i < (N); ++i)
    if (outdegree[i] == 0) dist[i] = 1e9;
  queue<int> Q;
  for (int i = 0; i < (N); ++i)
    if (indegree[i] == 0) {
      Q.push(i);
    }
  vector<int> sorted;
  for (int i = 0; i < (N); ++i) {
    if (Q.empty()) {
      cout << "NO\n";
      return 0;
    }
    int here = Q.front();
    Q.pop();
    sorted.push_back(here);
    for (auto &e : adj[here]) {
      int next = e.first;
      if (--indegree[next] == 0) {
        Q.push(next);
      }
    }
  }
  for (int i = 0; i < (N); ++i) {
    int curr = sorted[N - 1 - i];
    if (dist[curr] != -1) continue;
    int minX = 1e9, maxX = 0;
    for (auto &e : adj[curr]) {
      int next = e.first, d = e.second;
      minX = min(minX, dist[next] - d);
      maxX = max(maxX, dist[next] - d);
    }
    if (minX == maxX)
      dist[curr] = minX;
    else {
      cout << "NO\n";
      return 0;
    }
  }
  cout << "YES\n";
  return 0;
}
