#include <bits/stdc++.h>
using namespace std;
struct equation {
  int a;
  int b;
  int c;
};
int n, m;
bool exists(const map<int, int> table, int x) {
  return table.find(x) != table.end();
}
int apply(map<int, int>* table, const equation& equ) {
  bool find_a = exists(*table, equ.a);
  bool find_b = exists(*table, equ.b);
  if (find_a && find_b) {
    int c_desired = table->at(equ.a) - table->at(equ.b);
    return equ.c == c_desired ? 1 : 0;
  } else if (find_a) {
    int x_b = table->at(equ.a) - equ.c;
    (*table)[equ.b] = x_b;
    return 1;
  } else if (find_b) {
    int x_a = table->at(equ.b) + equ.c;
    (*table)[equ.a] = x_a;
    return 1;
  } else {
    assert(false);
  }
}
bool solve(const vector<equation>& equs) {
  vector<set<int> > connection(n + 1);
  for (int i = 0; i < equs.size(); i++) {
    int a = equs[i].a;
    int b = equs[i].b;
    connection[a].insert(i);
    connection[b].insert(i);
  }
  map<int, int> table;
  map<int, bool> visited;
  queue<int> q;
  for (int i = 0; i < equs.size(); i++) {
    const equation& e = equs[i];
    int a = e.a;
    if (visited[a]) continue;
    table[a] = 0;
    q.push(a);
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      if (visited[x]) continue;
      assert(exists(table, x));
      visited[x] = true;
      for (auto& y : connection[x]) {
        const equation& e2 = equs[y];
        int other = e2.a == x ? e2.b : e2.a;
        if (visited[other]) continue;
        if (!apply(&table, e2)) return false;
        q.push(other);
      }
    }
  }
  return true;
}
int main() {
  cin >> n >> m;
  vector<equation> equs(m);
  int a, b, c;
  for (int i = 0; i < m; i++) {
    cin >> a >> b >> c;
    equs[i].a = a;
    equs[i].b = b;
    equs[i].c = c;
  }
  if (solve(equs))
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
