#include <bits/stdc++.h>
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];
ll d[100001];
bool dijkstra(int s) {
  std::priority_queue<std::pair<ll, int>, std::vector<std::pair<ll, int> >,
                      std::greater<std::pair<ll, int> > >
      que;
  std::fill(d, d + 100001, (1LL << 62));
  bool ret = true, used[100001] = {false};
  d[s] = 0;
  que.push(std::make_pair(0, s));
  while (!que.empty()) {
    std::pair<ll, int> p = que.top();
    que.pop();
    int v = p.second, size_ = g[v].size();
    used[v] = true;
    if (d[v] < p.first) continue;
    for (int i = 0; i < size_; ++i) {
      edge e = g[v][i];
      if (d[e.to] > d[v] + e.cost) {
        if (d[e.to] != (1LL << 62) && !used[e.to]) {
          ret = false;
          break;
        }
        d[e.to] = d[v] + e.cost;
        que.push(std::make_pair(d[e.to], e.to));
      } else if (d[e.to] < d[v] + e.cost && d[e.to] != (1LL << 62) &&
                 d[v] != (1LL << 62) && !used[e.to]) {
        break;
        ret = false;
      }
    }
  }
  return ret;
}
int main() {
  cin.tie(0);
  std::ios::sync_with_stdio(false);
  int s = -1;
  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});
    g[R].push_back({L, D});
  }
  bool ans = dijkstra(s);
  if (ans || M == 1) {
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }
  return 0;
}
