#include <bits/stdc++.h>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using ll = long long;
struct edge {
  int to;
  ll cost;
  edge() {}
  edge(int to, ll cost) : to(to), cost(cost) {}
};
int N, M, L, R;
ll D;
std::vector<edge> g[100001];
std::vector<int> tsort() {
  int n = N;
  enum { YET, VISITED, DONE };
  std::vector<int> res, flg(n, YET);
  static const std::function<bool(int)> dfs = [&](int v) {
    flg[v] = VISITED;
    for (auto &e : g[v]) {
      int w = e.to;
      if (flg[w] != DONE && (flg[w] == VISITED || !dfs(w))) return false;
    }
    flg[v] = DONE;
    res.push_back(v);
    return true;
  };
  for (int i = 0; i < n; ++i)
    if (flg[i] == YET && !dfs(i)) return {};
  std::reverse(res.begin(), res.end());
  return res;
}
bool used[100001];
ll d[100001];
bool check(int s, ll dist, int cnt) {
  used[s] = true;
  d[s] = dist;
  bool ret = true;
  if (cnt == N) return true;
  for (edge v : g[s]) {
    if (!used[v.to]) {
      ret &= check(v.to, dist + v.cost, cnt + 1);
    } else if (used[v.to] && d[v.to] != -1) {
      if (dist + v.cost != d[v.to]) {
        return false;
      }
    }
  }
  return ret;
}
int main() {
  cin.tie(0);
  std::ios::sync_with_stdio(false);
  int s = -1;
  std::map<int, bool> mp;
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    cin >> L >> R >> D;
    L--, R--;
    if (s == -1) s = L;
    g[L].push_back({R, D});
  }
  std::vector<int> retG = tsort();
  std::memset(d, -1, sizeof d);
  bool ans = (retG.size() != 0 && check(retG[0], 0, 0));
  if (ans) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }
  return 0;
}
