#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
struct UnionFind {
  vector<int> par, rank;
  map<pair<int, int>, int> dis;
  UnionFind(int N) : par(N), rank(N) {
    for (int i = (0); i < (N); i++) par[i] = i, rank[i] = 0;
  }
  int root(int x) {
    if (par[x] == x) return x;
    return root(par[x]);
  }
  void unite(int x, int y, int z) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) {
      return;
    }
    if (x > y) {
      par[x] = y;
      dis[pair<int, int>(y, x)] = z;
    } else {
      par[y] = x;
      dis[pair<int, int>(x, y)] = z;
    }
  }
  bool distance(int x, int y, int z) {
    int rx = root(x);
    int ry = root(y);
    int sum = 0;
    if (rx != ry) {
      return true;
    } else {
      if (x > y) {
        int tmp = x;
        x = y;
        y = tmp;
      }
      while (par[y] != x && par[y] != par[x]) {
        sum += dis[pair<int, int>(par[y], y)];
        y = par[y];
      }
      sum += dis[pair<int, int>(x, y)];
    }
    if (sum == z) {
      return true;
    } else {
      return false;
    }
  }
};
int main() {
  int N, M;
  bool flag = true;
  cin >> N >> M;
  UnionFind tree(N);
  for (int i = (0); i < (M); i++) {
    int x, y, z;
    cin >> x >> y >> z;
    x -= 1;
    y -= 1;
    tree.unite(x, y, z);
    if (!tree.distance(x, y, z)) {
      flag = false;
    }
  }
  if (flag) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }
  return 0;
}
