#include <bits/stdc++.h>
using namespace std;
template <typename T>
void chmax(T &a, T b) {
  a = max(a, b);
}
template <typename T>
void chmin(T &a, T b) {
  a = min(a, b);
}
template <typename T>
void chadd(T &a, T b) {
  a = a + b;
}
long long int dx[] = {0, 0, 1, -1};
long long int dy[] = {1, -1, 0, 0};
const long long INF = 1001001001001001LL;
const long long MOD = 1000000007LL;
template <typename T>
struct Edge {
  long long int from, to;
  T cost;
  Edge() {}
  Edge(long long int s, T d) : to(s), cost(d) {}
  Edge(long long int f, long long int s, T d) : from(f), to(s), cost(d) {}
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
template <typename T>
vector<long long int> tpsort_Kahn(const vector<vector<Edge<T> > > &g) {
  const long long int V = g.size();
  vector<long long int> indeg(V, 0);
  stack<long long int> S;
  for (long long int(i) = (0); (i) < (V); (i)++)
    for (long long int(j) = (0); (j) < (g[i].size()); (j)++)
      indeg[g[i][j].to]++;
  for (long long int(i) = (0); (i) < (V); (i)++)
    if (indeg[i] == 0) S.push(i);
  vector<long long int> ans;
  while (S.size() > 0) {
    long long int u = S.top();
    S.pop();
    ans.push_back(u);
    for (long long int(i) = (0); (i) < (g[u].size()); (i)++) {
      indeg[g[u][i].to]--;
      if (indeg[g[u][i].to] == 0) S.push(g[u][i].to);
    }
  }
  return ans;
}
long long int N, M, deg[100010], dist[100010];
Edge<long long int> edges[100010];
signed main() {
  cin >> N >> M;
  vector<vector<Edge<long long int> > > G(N);
  for (long long int(i) = (0); (i) < (M); (i)++) {
    long long int L, R, D;
    cin >> L >> R >> D;
    L--;
    R--;
    G[L].push_back(Edge<long long int>(R, D));
    edges[i] = Edge<long long int>(L, R, D);
    deg[R]++;
  }
  vector<long long int> tp = tpsort_Kahn(G);
  if (tp.size() != N) {
    cout << "No" << endl;
    return 0;
  }
  fill(dist, dist + N, INF);
  for (long long int(i) = (0); (i) < (N); (i)++) {
    if (deg[i] == 0) {
      dist[i] = 0;
      priority_queue<pair<long long int, long long int>,
                     vector<pair<long long int, long long int> >,
                     greater<pair<long long int, long long int> > >
          que;
      que.push(make_pair(0, i));
      while (que.size()) {
        pair<long long int, long long int> cur = que.top();
        que.pop();
        long long int v = cur.second, cost = cur.first;
        for (auto x : G[v]) {
          if (dist[x.to] > dist[v] + x.cost) {
            dist[x.to] = dist[v] + x.cost;
            que.push(make_pair(dist[x.to], x.to));
          }
        }
      }
    }
  }
  bool ok = true;
  for (long long int(i) = (0); (i) < (M); (i)++) {
    Edge<long long int> e = edges[i];
    long long int u = e.from, v = e.to, d = e.cost;
    long long int diff = dist[v] - dist[u];
    ok &= (diff == d);
  }
  cout << (ok ? "Yes" : "No") << endl;
  return 0;
}
