#include <bits/stdc++.h>
using namespace std;
long long int max(long long int a, long long int b) { return a >= b ? a : b; }
int main() {
  long long int n, m;
  vector<long long int> l;
  vector<long long int> r;
  vector<long long int> d;
  map<long long int, map<long long int, long long int>> x;
  map<long long int, vector<long long int>> y;
  set<long long int> flag;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    long long int tmp1, tmp2, tmp3;
    cin >> tmp1 >> tmp2 >> tmp3;
    l.push_back(tmp1);
    r.push_back(tmp2);
    d.push_back(tmp3);
    x[tmp1][tmp2] = tmp3;
    x[tmp2][tmp1] = -tmp3;
    y[tmp1].push_back(tmp2);
    y[tmp2].push_back(tmp1);
  }
  for (int i = 1; i <= n; i++) {
    if (flag.count(i) == 1) {
      break;
    }
    flag.insert(i);
    queue<long long int> q;
    q.push(i);
    map<long long int, long long int> field;
    field[i] = 10000000;
    while (q.size() != 0) {
      long long int now = q.front();
      long long int size = y[now].size();
      if (0) cout << "now=" << now << endl;
      q.pop();
      for (int i = 0; i < size; i++) {
        long long int next = y[now].at(i);
        if (flag.count(next) == 0) {
          field[next] = field[now] + x[now][next];
          if (0)
            cout << "next=" << next << " field[next]=" << field[next] << endl;
          flag.insert(next);
          q.push(next);
        } else {
          if (0) cout << "confirm" << endl;
          if (0) cout << "now=" << now << " next=" << next << endl;
          auto itr = x[now].find(next);
          if (itr != x[now].end()) {
            long long int query = x[now][next];
            long long int sure = field[next] - field[now];
            if (0) cout << "query=" << query << "sure=" << sure << endl;
            if (query != sure) {
              if (0) cout << "x[now][next] = " << x[now][next] << endl;
              cout << "NO" << endl;
              return 0;
            }
          }
        }
      }
    }
  }
  cout << "YES" << endl;
  return 0;
}
