#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
template <typename T>
void print_sequential_container(ostream& stream, const vector<T>& c) {
  stream << "[";
  auto& last = *(--c.end());
  for (auto& e : c) {
    stream << e;
    if (e != last) {
      stream << ", ";
    }
  }
  stream << "]";
}
template <typename T>
void print_array(ostream& stream, T a[], int n) {
  stream << "[";
  for (int i = 0; i < n; i++) {
    stream << a[i];
    if (i != n - 1) {
      stream << ", ";
    }
  }
  stream << "]";
}
template <typename T>
void print_set(ostream& stream, const T& c) {
  stream << "{";
  auto& last = *(--c.end());
  for (auto& e : c) {
    stream << e;
    if (e != last) {
      stream << ", ";
    }
  }
  stream << "}";
}
template <typename T>
void print_map(ostream& stream, const T& c) {
  stream << "{";
  auto& last = *(--c.end());
  for (auto& e : c) {
    stream << e.first << ": " << e.second;
    if (e != last) {
      stream << ", ";
    }
  }
  stream << "}";
}
template <typename T>
ostream& operator<<(ostream& stream, const vector<T>& c) {
  print_sequential_container(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const list<T>& c) {
  print_sequential_container(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const forward_list<T>& c) {
  print_sequential_container(stream, c);
  return stream;
}
template <typename T, size_t N>
ostream& operator<<(ostream& stream, const array<T, N>& c) {
  print_sequential_container(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const deque<T>& c) {
  print_sequential_container(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const stack<T>& c) {
  vector<T> v;
  while (not c.empty()) {
    v.push_back(c.top());
    c.pop();
  }
  for (int i = ((int)v.size()) - 1; i >= 0; i--) {
    c.push(v[i]);
  }
  print_sequential_container(stream, v);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const queue<T>& c) {
  vector<T> v;
  while (not c.empty()) {
    v.push_back(c.front());
    c.pop();
  }
  for (T e : v) {
    c.push(e);
  }
  print_sequential_container(stream, v);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const priority_queue<T>& c) {
  vector<T> v;
  while (not c.empty()) {
    v.push_back(c.top());
    c.pop();
  }
  for (T e : v) {
    c.push(e);
  }
  print_sequential_container(stream, v);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const set<T>& c) {
  print_set(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const unordered_set<T>& c) {
  print_set(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const multiset<T>& c) {
  print_set(stream, c);
  return stream;
}
template <typename T>
ostream& operator<<(ostream& stream, const unordered_multiset<T>& c) {
  print_set(stream, c);
  return stream;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& stream, const map<T1, T2>& c) {
  print_map(stream, c);
  return stream;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& stream, const unordered_map<T1, T2>& c) {
  print_map(stream, c);
  return stream;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& stream, const multimap<T1, T2>& c) {
  print_map(stream, c);
  return stream;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& stream, const unordered_multimap<T1, T2>& c) {
  print_map(stream, c);
  return stream;
}
template <typename T1, typename T2>
ostream& operator<<(ostream& stream, const pair<T1, T2>& p) {
  stream << "(" << p.first << ", " << p.second << ")";
  return stream;
}
template <typename T>
size_t make_hash(const T& v) {
  return std::hash<T>()(v);
}
size_t hash_combine(const size_t& h, const size_t& v) {
  return h ^ (v + 0x9e3779b9 + (h << 6) + (h >> 2));
}
namespace std {
template <typename T1, typename T2>
struct hash<pair<T1, T2>> {
 public:
  size_t operator()(const pair<T1, T2>& p) const {
    return hash_combine(make_hash(p.first), make_hash(p.second));
  }
};
};  // namespace std
template <typename T>
struct hash_container {
  size_t operator()(const T& c) const {
    size_t h = 0;
    for (const auto& e : c) {
      h = hash_combine(h, make_hash(e));
    }
    return h;
  }
};
template <typename T>
bool amin(T& a, T b) {
  return a > b ? (a = b, true) : false;
}
template <typename T>
bool amax(T& a, T b) {
  return a < b ? (a = b, true) : false;
}
const int mod = 1000000007;
const int inf = 1000000000;
const long long infll = (long long)inf * (long long)inf;
const int maxn = 100100;
vector<vector<pair<int, int>>> g;
vector<char> used;
vector<long long> pos;
bool dfs(int i, int p) {
  pos[i] = p;
  used[i] = 1;
  bool res = true;
  for (auto w : g[i]) {
    int j = w.first, d = w.second;
    if (!used[j]) {
      res = dfs(j, p + d);
    } else {
      if (pos[j] - pos[i] != d) {
        ;
        ;
        ;
        ;
        ;
        res = false;
      }
    }
    if (not res) {
      break;
    }
  }
  return res;
}
class TaskB {
 public:
  void solve(istream& in, ostream& out) {
    g.clear();
    used.clear();
    pos.clear();
    int n, m;
    in >> n >> m;
    g.resize(n);
    used.resize(n, 0);
    pos.resize(n);
    for (int i = 0; i < (int)(m); ++i) {
      int l, r, d;
      in >> l >> r >> d;
      --l;
      --r;
      g[l].push_back({r, d});
      g[r].push_back({l, -d});
    }
    for (int i = 0; i < (int)(n); ++i) {
      if (!used[i]) {
        fill((pos).begin(), (pos).end(), infll);
        bool res = dfs(i, 0);
        if (not res) {
          out << "No";
          return;
        }
        long long mmin = 2 * inf + 100, mmax = -2 * inf - 100;
        for (auto p : pos) {
          if (p != infll) {
            mmin = min(mmin, p);
            mmax = max(mmax, p);
          }
        }
        if (mmax - mmin > inf) {
          out << "No";
          return;
        }
      }
    }
    out << "Yes";
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  TaskB solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  return 0;
}
