#include <bits/stdc++.h>
using namespace std;
const int32_t inf = 1001001001;
const int64_t infll = 1001001001001001001ll;
const int dx[] = {0, -1, 1, 0, -1, 1, -1, 1},
          dy[] = {-1, 0, 0, 1, -1, -1, 1, 1};
template <typename T>
using vector2d = vector<vector<T>>;
template <typename T>
void sort(vector<T> &v) {
  sort(v.begin(), v.end());
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &v) {
  os << v[0];
  for (int i = 1; i < v.size(); ++i) os << " " << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, pair<T1, T2> p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}
struct IoSetup {
  IoSetup() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;
inline int64_t in() {
  int64_t x = 0;
  cin >> x;
  return x;
}
template <typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) {
  return a < b && (a = b, true);
}
template <typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) {
  return a > b && (a = b, true);
}
signed main(int argc, char *argv[]) {
  int n = in(), m = in();
  map<pair<int, int>, int> d;
  vector2d<int> r(n);
  for (int i = 0; i < m; ++i) {
    int L = in() - 1, R = in() - 1, D = in();
    if (L > R) {
      swap(L, R);
      D *= -1;
    }
    d[make_pair(L, R)] = D;
    r[R].emplace_back(L);
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < (int)r[i].size() - 1; ++j) {
      int u = r[i][j], v = r[i][j + 1];
      if (u > v) swap(u, v);
      if (d.count(make_pair(u, v))) {
        if (d[make_pair(u, i)] - d[make_pair(v, i)] != d[make_pair(u, v)]) {
          cout << "No" << endl;
          return 0;
        }
      }
    }
  }
  cout << "Yes" << endl;
}
