#include <cstdio>

#include <cstring>

#include <string>
#include <vector>
#include <algorithm>

#include <set>
#include <map>

using namespace std;

#define SZ(a) int((a).size())
#define REP(i,n) for(int i=0,_n=(n);i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)

typedef long long llong;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef pair<int,int> II;

struct Edge {
   int u, v, dist;
};

#define MAXN 100004
#define MAXM 200004
int N, M;
Edge edges[MAXM];
VI adj[MAXN];
VI rev_adj[MAXN];

bool cycle;
VI dfs_color;
VI top_sort_list;
void dfs(int u) {
   dfs_color[u] = 1;   // color gray
   for (int eid : adj[u]) {
      int v = edges[eid].v;
      if (dfs_color[v] == 0)
         dfs(v);
      else if (dfs_color[v] == 1) // back edge -> cycle
         cycle = true;
   }
   dfs_color[u] = 2;  // color black
   top_sort_list.push_back(u);
}
bool topological_sort_dfs() {
   top_sort_list.clear();
   cycle = false;
   dfs_color = VI(N, 0);  // color all nodes initially white
   for (int u = 0; u < N; ++u)
      if (dfs_color[u] == 0)
         dfs(u);
   if (cycle) {
      top_sort_list.clear();
      return false;
   }
   reverse(top_sort_list.begin(), top_sort_list.end());
   return true;
}

const int INF = 1000000001;
int X[MAXN];
VI new_visited2;
bool dfs2(int u, int d = 0) {
   if (X[u] != -INF)
      return d == X[u];
   new_visited2.push_back(u);
   X[u] = d;
   for (int eid : adj[u]) {
      int v = edges[eid].v;
      if ( !dfs2(v, d + edges[eid].dist) )
         return false;
   }
   return true;
}

VI new_visited3;
bool dfs3(int v, int d) {
   if (X[v] != -INF)
      return d == X[v];
   new_visited3.push_back(v);
   X[v] = d;
   for (int eid : rev_adj[v]) {
      int u = edges[eid].u;
      if ( !dfs3(u, d - edges[eid].dist) )
         return false;
   }
   return true;
}

bool solve() {
   if (!topological_sort_dfs())
      return false;
   VI in_deg(N);
   REP(j, M) {
      int v = edges[j].v;
      in_deg[v]++;
   }
   VI top_sort_order(N);
   set<int> avail;
   REP(i, N) {
      int u = top_sort_list[i];
   // fprintf(stderr, "%d ", u+1);
      top_sort_order[u] = i;
      avail.insert(i);
   }
   //fprintf(stderr, "\n");

   REP(u, N)
      X[u] = -INF;

   while (!avail.empty()) {
      int i = *avail.begin();
      int u = top_sort_list[i];
      new_visited2.clear();
      if (!dfs2(u)) {
      //   fprintf(stderr, "HERE2 %d\n", u+1);
         return false;
      }

      for (int v : new_visited2) {
         for (int eid : rev_adj[v]) {
            int w = edges[eid].u;
            if (!dfs3(w, X[v] - edges[eid].dist)) {
            //   fprintf(stderr, "HERE3\n");
               return false;
            }
         }
      }

      for (int v : new_visited2)
         avail.erase( top_sort_order[v] );
      for (int v : new_visited3)
         avail.erase( top_sort_order[v] );
   }

   return true;
}


int main(int argc, char* argv[]) {
   scanf("%d %d", &N, &M);
   REP(j, M) {
      int u, v, dist;
      scanf("%d %d %d", &u, &v, &dist);
      --u, --v;
      edges[j] = {u, v, dist};
      adj[u].push_back(j);
      rev_adj[v].push_back(j);
   }

   bool res = solve();
   puts(res ? "Yes" : "No");

   return 0;
}


Measured memory_bytes: 24316