#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-10;
const long long INFLL = (long long)(1e9) * (long long)(1e9);
const int INF = 1e9;
template <class T>
void chmin(T& a, const T b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T b) {
  if (a < b) a = b;
}
const long long pow(const long long p, const long long q) {
  long long t = 1;
  for (int i = 0; i < q; i++) t *= p;
  return t;
}
template <typename T>
struct has_iter {
 private:
  template <typename U>
  static constexpr true_type check(typename U::iterator*);
  template <typename U>
  static constexpr false_type check(...);

 public:
  static constexpr bool value = decltype(check<T>(nullptr))::value;
};
template <typename T, typename U = typename T::iterator>
void print(const T& container) {
  auto &&first = begin(container), last = end(container);
  auto&& back = prev(last);
  for (auto e = first; e != last; e = next(e)) cout << *e << " \n"[e == back];
}
extern void* enabler;
template <typename Head,
          typename enable_if<!has_iter<Head>::value>::type*& = enabler>
void print(const Head& head) {
  cout << head << endl;
}
template <typename Head, typename... Tail>
void print(const Head& head, const Tail&... tail) {
  cout << head << " ";
  print(tail...);
}
void io_speedup() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}
template <typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  for (T& x : vec) is >> x;
  return is;
}
template <typename T>
vector<T> read(int n) {
  vector<T> t(n);
  cin >> t;
  return t;
}
template <typename T>
T read() {
  T t;
  cin >> t;
  return t;
}
int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<pair<int, int>>> g(n);
  vector<int> pos(n, INF);
  vector<char> root(n, 1);
  for (int i = (0); i < (int)(m); ++i) {
    int l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    if (d == 0) {
      if (l > r) swap(l, r);
    }
    g[l].push_back(pair<int, int>(r, d));
    root[r] = 0;
  }
  vector<char> reach(n);
  bool flag = 1;
  function<void(int)> dfs = [&](int v) {
    reach[v] = 1;
    for (auto&& e : g[v]) {
      int r, d;
      tie(r, d) = e;
      if (pos[r] == INF)
        pos[r] = pos[v] + d;
      else {
        if (pos[r] != pos[v] + d) {
          flag = 0;
        }
      }
    }
    for (auto&& e : g[v]) dfs(e.first);
  };
  for (int i = (0); i < (int)(n); ++i)
    if (root[i]) {
      pos[i] = 0;
      dfs(i);
      reach[i] = 1;
    }
  for (int i = (0); i < (int)(n); ++i)
    if (!reach[i]) flag = 0;
  if (flag)
    print("Yes");
  else
    print("No");
}
