#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
template <class T>
T& chmin(T& a, const T& b) {
  return a = min(a, b);
}
template <class T>
T& chmax(T& a, const T& b) {
  return a = max(a, b);
}
template <class T>
istream& operator>>(istream& is, vector<T>& v) {
  for (auto& i : v) is >> i;
  return is;
}
template <class T>
ostream& operator<<(ostream& os, vector<T>& v) {
  const string delimiter = "\n";
  for (int i = (int)(0); i < (int)(v.size()); i++) {
    os << v[i];
    if (i != v.size() - 1) os << delimiter;
  }
  return os;
}
struct Edge {
  int from, to;
  int cost;
  bool operator<(const Edge& e) const { return cost < e.cost; }
  bool operator>(const Edge& e) const { return cost > e.cost; }
};
void add_edge(vector<vector<Edge>>& g, int from, int to, int cost) {
  g[from].push_back(Edge{from, to, cost});
}
const int INF = 1e-9;
int n, m;
vector<tuple<int, int, int>> v;
int main() {
  cin.sync_with_stdio(false);
  cout << fixed << setprecision(10);
  cin >> n >> m;
  vector<vector<Edge>> g(n);
  for (int i = (int)(0); i < (int)(m); i++) {
    int l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    v.emplace_back(l, r, d);
    add_edge(g, l, r, d);
    add_edge(g, r, l, -d);
  }
  vector<int> dist(n, INF);
  for (int i = (int)(0); i < (int)(n); i++) {
    if (dist[i] != INF) continue;
    dist[i] = 0;
    queue<int> que;
    que.push(i);
    while (!que.empty()) {
      int t = que.front();
      que.pop();
      for (auto e : g[t]) {
        if (dist[e.to] != INF) continue;
        dist[e.to] = dist[t] + e.cost;
        que.push(e.to);
      }
    }
  }
  bool ans = true;
  for (auto t : v) {
    int l, r, d;
    tie(l, r, d) = t;
    if (dist[r] - dist[l] != d) ans = false;
  }
  cout << (ans ? "Yes" : "No") << endl;
  return 0;
}
