#include <bits/stdc++.h>
using namespace std;
int prior;
struct equation {
  int a;
  int b;
  int c;
  bool operator<(const equation& r) const {
    if (prior == a || prior == b) {
      return true;
    } else if (prior == r.a || prior == r.b) {
      return false;
    } else {
      return a < r.a;
    }
  };
};
int n, m;
void print_equ(const equation& equ) {
  cout << "x_" << equ.a << " - ";
  cout << "x_" << equ.b << " = ";
  cout << equ.c << endl;
}
void print_equs(const vector<equation>& equs) {
  for (int i = 0; i < equs.size(); i++) {
    print_equ(equs[i]);
  }
}
int apply(map<int, int>* table, const equation& equ) {
  auto ite_a = table->find(equ.a);
  auto ite_b = table->find(equ.b);
  bool find_a = ite_a != table->end();
  bool find_b = ite_b != table->end();
  if (find_a && find_b) {
    int c_desired = ite_a->second - ite_b->second;
    return equ.c == c_desired ? 1 : 0;
  } else if (find_a) {
    int x_b = ite_a->second - equ.c;
    (*table)[equ.b] = x_b;
    return 1;
  } else if (find_b) {
    int x_a = ite_b->second + equ.c;
    (*table)[equ.a] = x_a;
    return 1;
  } else {
    return -1;
  }
}
void sort_equs(vector<equation>* equs) {
  assert(equs != nullptr);
  vector<int> cnt(n, 0);
  for (int i = 0; i < equs->size(); i++) {
    int a = (*equs)[i].a;
    int b = (*equs)[i].b;
    assert(0 < a && a <= n);
    assert(0 < b && b <= n);
    cnt[a - 1]++;
    cnt[b - 1]++;
  }
  int max_index = 0;
  for (int i = 1; i < cnt.size(); i++) {
    if (cnt[max_index] < cnt[i]) max_index = i;
  }
  prior = max_index + 1;
  sort(equs->begin(), equs->end());
}
void print_table(const map<int, int>& table) {
  for (auto& v : table) {
    cout << v.first << ":" << v.second << endl;
  }
}
bool update(const vector<equation>& equs, map<int, int>* table,
            vector<equation>* delayed) {
  for (int i = 0; i < equs.size(); i++) {
    switch (apply(table, equs[i])) {
      case -1:
        if (delayed != nullptr) delayed->push_back(equs[i]);
        break;
      case 0:
        print_table(*table);
        cout << "failed: ";
        print_equ(equs[i]);
        return false;
      case 1:
        break;
      default:
        assert(false);
    }
  }
  return true;
}
bool try_2times(vector<equation>* equs, map<int, int>* table,
                vector<equation>* delayed) {
  sort_equs(equs);
  vector<equation> delayed_first;
  (*table)[prior] = 0;
  bool result = update(*equs, table, &delayed_first);
  if (!result) return false;
  if (delayed_first.size() == 0) return true;
  sort_equs(&delayed_first);
  result = update(delayed_first, table, delayed);
  if (!result) return false;
  return true;
}
bool solve(vector<equation>* equs) {
  map<int, int> table;
  vector<equation> delayed;
  bool result = try_2times(equs, &table, &delayed);
  if (!result) return false;
  if (result && delayed.size() == 0) return true;
  vector<equation> delayed2;
  result = try_2times(&delayed, &table, &delayed2);
  if (!result) return false;
  if (result && delayed2.size() == 0) return true;
  assert(false);
}
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;
}
