#include <bits/stdc++.h>
using namespace std;
struct point {
  int y, cost;
  point() { y = cost = 0; }
  point(int _y, int _cost) {
    y = _y;
    cost = _cost;
  }
  inline bool operator<(const point &x) const { return cost > x.cost; }
};
struct input {
  int x, y, cost;
  input() {}
  input(int _x, int _y, int _cost) {
    x = _x;
    y = _y;
    cost = _cost;
  }
};
vector<point> G[100001];
priority_queue<point> c;
int d[100001];
int N, M;
void dijkstra(int x) {
  int viz[100001];
  for (int i = 1; i <= N; ++i) {
    d[i] = 1 << 30;
    viz[i] = 0;
  }
  d[x] = 0;
  int nod, next;
  c.push(point(1, 0));
  while (!c.empty()) {
    nod = c.top().y;
    c.pop();
    if (viz[nod] == 0) {
      viz[nod] = 1;
      for (vector<point>::iterator it = G[nod].begin(); it != G[nod].end();
           ++it) {
        next = it->y;
        if (d[next] > d[nod] + it->cost) {
          d[next] = d[nod] + it->cost;
          c.push(point(next, d[next]));
        }
      }
    }
  }
}
int main() {
  int l, r, dist;
  int x, y, cost;
  cin >> N >> M;
  input in[100001];
  for (int i = 1; i <= M; ++i) {
    cin >> l >> r >> dist;
    in[i] = input(l, r, dist);
    G[l].push_back(point(r, dist));
    G[r].push_back(point(l, dist));
  }
  dijkstra(1);
  for (int i = 1; i <= M; ++i) {
    x = in[i].x;
    y = in[i].y;
    cost = in[i].cost;
    if (x != 1 && y != 1) {
      if (fabs(d[x] - d[y]) != cost) {
        cout << "No";
        return 0;
      }
    } else {
      if (x == 1 && d[y] != cost) {
        cout << "No";
        return 0;
      }
      if (y == 1 && d[x] != cost) {
        cout << "No";
        return 0;
      }
    }
  }
  cout << "Yes";
  return 0;
}
