#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
const ll INF = 1LL << 60;
const int INF_INT = 1 << 30;
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
struct mll {
  static ll MOD;
  ll val;
  mll(ll v = 0) : val(v % MOD) {
    if (val < 0) val += MOD;
  }
  mll operator-() const { return -val; }
  mll operator+(const mll &b) const { return val + b.val; }
  mll operator-(const mll &b) const { return val - b.val; }
  mll operator*(const mll &b) const { return val * b.val; }
  mll operator/(const mll &b) const { return mll(*this) /= b; }
  mll operator+(ll b) const { return *this + mll(b); }
  mll operator-(ll b) const { return *this - mll(b); }
  mll operator*(ll b) const { return *this * mll(b); }
  friend mll operator+(ll a, const mll &b) { return b + a; }
  friend mll operator-(ll a, const mll &b) { return -b + a; }
  friend mll operator*(ll a, const mll &b) { return b * a; }
  mll &operator+=(const mll &b) {
    val = (val + b.val) % MOD;
    return *this;
  }
  mll &operator-=(const mll &b) {
    val = (val + MOD - b.val) % MOD;
    return *this;
  }
  mll &operator*=(const mll &b) {
    val = (val * b.val) % MOD;
    return *this;
  }
  mll &operator/=(const mll &b) {
    ll c = b.val, d = MOD, u = 1, v = 0;
    while (d) {
      ll t = c / d;
      c -= t * d;
      swap(c, d);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0) val += MOD;
    return *this;
  }
  mll &operator+=(ll b) { return *this += mll(b); }
  mll &operator-=(ll b) { return *this -= mll(b); }
  mll &operator*=(ll b) { return *this *= mll(b); }
  mll &operator/=(ll b) { return *this /= mll(b); }
  bool operator==(const mll &b) { return val == b.val; }
  bool operator!=(const mll &b) { return val != b.val; }
  bool operator==(ll b) { return *this == mll(b); }
  bool operator!=(ll b) { return *this != mll(b); }
  friend bool operator==(ll a, const mll &b) { return mll(a) == b.val; }
  friend bool operator!=(ll a, const mll &b) { return mll(a) != b.val; }
  friend ostream &operator<<(ostream &os, const mll &a) { return os << a.val; }
  friend istream &operator>>(istream &is, mll &a) { return is >> a.val; }
  static mll Combination(ll a, ll b) {
    chmin(b, a - b);
    if (b < 0) return mll(0);
    mll c = 1;
    for (ll i = (0); i <= (b - 1); i++) c *= a - i;
    for (ll i = (0); i <= (b - 1); i++) c /= i + 1;
    return c;
  }
};
using vmll = std::vector<mll>;
using vvmll = std::vector<vmll>;
using vvvmll = std::vector<vvmll>;
using vvvvmll = std::vector<vvvmll>;
struct Fast {
  Fast() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(std::numeric_limits<double>::max_digits10);
  }
} fast;
ll mll::MOD = (ll)(1e9 + 7);
struct Node {
  ll next;
  ll cost;
  Node(ll next, ll cost) {
    this->next = next;
    this->cost = cost;
  }
  Node() {}
};
int main() {
  ll N;
  cin >> N;
  ll M;
  cin >> M;
  vll L(M);
  vll R(M);
  vll D(M);
  for (ll i = (0); i <= (M - 1); i++) {
    cin >> L[i] >> R[i] >> D[i];
    L[i]--;
    R[i]--;
  }
  vector<vector<Node>> graph(N, vector<Node>(0));
  for (ll i = (0); i <= (M - 1); i++) {
    graph[L[i]].push_back(Node(R[i], D[i]));
    graph[R[i]].push_back(Node(L[i], -D[i]));
  }
  bool result = true;
  vector<bool> visited(N, false);
  for (ll i = (0); i <= (N - 1); i++) {
    if (visited[i] == true) {
      continue;
    }
    queue<ll> q;
    q.push(i);
    vll dist(N, -1);
    dist[i] = 0;
    while (q.empty() == false) {
      ll node = q.front();
      q.pop();
      visited[node] = true;
      for (auto next : graph[node]) {
        ll nextDist = dist[node] + next.cost;
        if (dist[next.next] >= 0 && dist[next.next] != nextDist) {
          result = false;
          break;
        }
        if (visited[next.next] == false) {
          dist[next.next] = nextDist;
          q.push(next.next);
        }
      }
      if (result == false) {
        break;
      }
    }
    if (result == false) {
      break;
    }
  }
  if (result) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }
  return 0;
}
