#include <bits/stdc++.h>
using namespace std;
const long long INF = INT64_MAX;
class Vertex {
 public:
  long long idx;
  long long param = -1;
  long long dist = INF;
  vector<pair<Vertex *, long long> > e;
  long long size() { return e.size(); }
  void init() { dist = INF; }
  bool operator==(const Vertex *o) { return dist == o->dist; }
  bool operator!=(const Vertex *o) { return dist != o->dist; }
  bool operator>(const Vertex *o) { return dist > o->dist; }
  bool operator<(const Vertex *o) { return dist < o->dist; }
  bool operator>=(const Vertex *o) { return dist >= o->dist; }
  bool operator<=(const Vertex *o) { return dist <= o->dist; }
};
class Graph {
 public:
  vector<Vertex *> V;
  vector<long long> order;
  typedef tuple<Vertex *, Vertex *, long long> Edge;
  vector<Edge> E;
  Graph(long long siz) {
    for (int i = 0; i < siz; i++) {
      auto v = new Vertex();
      v->idx = i;
      V.push_back(v);
    }
  }
  void initdist() {
    for (auto &v : V) {
      v->init();
    }
  }
  static bool comp(const Edge &e1, const Edge &e2) {
    return get<2>(e1) < get<2>(e2);
  }
  Vertex *getVertex(long long idx) { return V[idx]; }
  void unite(long long from, long long to, long long w = 1,
             bool digraph = true) {
    E.push_back(make_tuple(V[from], V[to], w));
    V[from]->e.push_back(make_pair(V[to], w));
    if (!digraph) {
      E.push_back(make_tuple(V[to], V[from], w));
      V[to]->e.push_back(make_pair(V[from], w));
    }
  }
  void dijkstra(long long start) {
    priority_queue<Vertex *, vector<Vertex *>, greater<Vertex *> > pq;
    Vertex *s = getVertex(start);
    s->dist = 0;
    pq.push(s);
    while (!pq.empty()) {
      Vertex *v = pq.top();
      pq.pop();
      for (auto &u : v->e) {
        if (u.first->dist > v->dist + u.second) {
          u.first->dist = v->dist + u.second;
          pq.push(u.first);
        }
      }
    }
  }
  bool sort() {
    for (auto &v : V) {
      if (v->param == -1 && !sort_visit(v->idx)) {
        return false;
      }
    }
    reverse(order.begin(), order.end());
    return true;
  }
  bool sort_visit(int v) {
    Vertex *_v = getVertex(v);
    _v->param = 1;
    if (!_v->e.empty()) {
      for (auto &u : _v->e) {
        if (u.first->param == 2) continue;
        if (u.first->param == 1) return false;
        if (!sort_visit(u.first->idx)) return false;
      }
    }
    order.push_back(v);
    _v->param = 2;
    return true;
  }
};
int main() {
  long long N, M;
  cin >> N >> M;
  Graph *g = new Graph(N);
  for (int i = 0; i < M; i++) {
    long long l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    g->initdist();
    g->dijkstra(l);
    if (g->getVertex(r)->dist == INF) {
      g->unite(l, r, d, false);
    } else {
      if (g->getVertex(r)->dist != d) {
        cout << "No" << endl;
        return 0;
      }
    }
  }
  cout << "Yes" << endl;
}
