#include <bits/stdc++.h>
using namespace std;
template <typename T>
std::string printVector(const std::vector<T> &data) {
  std::stringstream ss;
  std::ostream_iterator<T> out_it(ss, ", ");
  ss << "[";
  std::copy(data.begin(), data.end() - 1, out_it);
  ss << data.back() << "]";
  return ss.str();
}
const int MOD = 1e9 + 7;
const long long LINF = 1001002003004005006ll;
const int INF = 1001001001;
vector<pair<int, long long>> adjlist[101010];
bool used[101010];
bool flag = 0;
void bfs(int i) {
  ;
  queue<int> que;
  long long dist[101010];
  for (int j = (0); j < (101010); ++j) dist[j] = -LINF;
  dist[i] = 0;
  used[i] = true;
  que.push(i);
  while (!que.empty()) {
    int p = que.front();
    que.pop();
    ;
    used[p] = true;
    for (auto r : adjlist[p]) {
      if (dist[r.first] == -LINF) {
        ;
        dist[r.first] = dist[p] + r.second;
        que.push(r.first);
        ;
        ;
        ;
        ;
      } else {
        if (dist[r.first] != dist[p] + r.second) {
          ;
          ;
          ;
          ;
          ;
          flag = 1;
          return;
        }
      }
    }
  }
}
signed main(int argc, char const *argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  for (int i = (0); i < (101010); ++i) used[i] = false;
  for (int i = (0); i < (M); ++i) {
    int L, R;
    long long D;
    cin >> L >> R >> D;
    L--;
    R--;
    adjlist[L].emplace_back(R, D);
    adjlist[R].emplace_back(L, -D);
  }
  for (int i = (0); i < (N); ++i) {
    if (used[i] == true) continue;
    bfs(i);
    if (flag == 1) {
      cout << "No" << endl;
      return 0;
    }
  }
  cout << "Yes" << endl;
}
