#include <bits/stdc++.h>
using namespace std;
template <class T>
using vv = vector<vector<T> >;
template <typename T>
ostream& operator<<(ostream& s, const vector<T>& v) {
  int len = v.size();
  s << "\n";
  for (int(i) = (0); (i) < (len); ++(i)) {
    s << v[i];
    if (i < len - 1) {
      s << "\t";
    }
  }
  s << "\n";
  return s;
}
template <typename T>
ostream& operator<<(ostream& s, const vector<vector<T> >& vv) {
  int len = vv.size();
  for (int(i) = (0); (i) < (len); ++(i)) {
    s << vv[i];
  }
  return s;
}
template <typename T>
ostream& operator<<(ostream& s, const deque<T>& v) {
  int len = v.size();
  s << "\n";
  for (int(i) = (0); (i) < (len); ++(i)) {
    s << v[i];
    if (i < len - 1) {
      s << "\t";
    }
  }
  s << "\n";
  return s;
}
template <typename T>
ostream& operator<<(ostream& s, const deque<deque<T> >& vv) {
  int len = vv.size();
  for (int(i) = (0); (i) < (len); ++(i)) {
    s << vv[i];
  }
  return s;
}
template <typename T>
ostream& operator<<(ostream& s, const set<T>& v) {
  s << "\n";
  for (auto elm : v) {
    s << elm << "\t";
  }
  s << "\n";
  return s;
}
inline void scan(int& a) { scanf("%d", &a); }
inline void scan(int& a, int& b) { scanf("%d%d", &a, &b); }
inline void scan(int& a, int& b, int& c) { scanf("%d%d%d", &a, &b, &c); }
inline void scan(int& a, int& b, int& c, int& d) {
  scanf("%d%d%d%d", &a, &b, &c, &d);
}
inline void scan(vector<int>& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(vector<vector<int> >& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(long long& a) { scanf("%lld", &a); }
inline void scan(long long& a, long long& b) { scanf("%lld%lld", &a, &b); }
inline void scan(long long& a, long long& b, long long& c) {
  scanf("%lld%lld%lld", &a, &b, &c);
}
inline void scan(long long& a, long long& b, long long& c, long long& d) {
  scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
}
inline void scan(vector<long long>& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(vector<vector<long long> >& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(char& a) { scanf(" %c", &a); }
inline void scan(vector<char>& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(vector<vector<char> >& v) {
  int sz = v.size();
  for (int(i) = (0); (i) < (sz); ++(i)) {
    scan(v[i]);
  }
}
inline void scan(string& s) {
  char BUF[3000000];
  scanf(" %s", BUF);
  s = string(BUF);
}
inline void print(int a) { printf("%d\n", a); }
inline void print(int a, int b) { printf("%d %d\n", a, b); }
inline void print(long long a) { printf("%lld\n", a); }
inline void print(long long a, long long b) { printf("%lld %lld\n", a, b); }
inline void print(string s) { cout << s << "\n"; }
inline void print_yn(bool flg) {
  if (flg) {
    printf("Yes\n");
  } else {
    printf("No\n");
  }
}
class UF {
 private:
  vector<int> data;
  void init(int n) { data.assign(n, -1); }

 public:
  UF() {}
  UF(int n) { init(n); }
  int root(int x) {
    if (data[x] < 0) return x;
    return data[x] = root(data[x]);
  }
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  int size(int x) { return -data[root(x)]; }
  bool same(int x, int y) { return root(x) == root(y); }
};
vv<vector<int> > g;
int main() {
  int n, m;
  scan(n, m);
  g.resize(n);
  auto uf = UF(n);
  for (int(i) = (0); (i) < (m); ++(i)) {
    int l, r, d;
    scan(l, r, d);
    l--;
    r--;
    g[l].push_back({r, d});
    g[r].push_back({l, -d});
    uf.unite(l, r);
  }
  int max_width = 1e9;
  vector<bool> calced(n, false);
  for (int(i) = (0); (i) < (n); ++(i)) {
    if (calced[uf.root(i)]) {
      continue;
    }
    calced[uf.root(i)] = true;
    deque<int> stk;
    stk.push_back(i);
    vector<bool> reached(n, false);
    vector<int> x(n, 0);
    int mi = 0;
    int ma = 0;
    while (!stk.empty()) {
      int u = stk.front();
      stk.pop_front();
      for (auto e : g[u]) {
        int v = e[0];
        if (reached[v]) {
          if (x[v] != x[u] + e[1]) {
            printf("No\n");
            return 0;
          }
          continue;
        }
        reached[v] = true;
        x[v] = x[u] + e[1];
        mi = min(mi, x[v]);
        ma = max(ma, x[v]);
        stk.push_back(v);
      }
    }
    if (ma - mi > max_width) {
      printf("No\n");
      return 0;
    }
  }
  printf("Yes\n");
  return 0;
}
