// Slower C++ solution:
#include <vector>

#include <stack>

#include <iostream>



using namespace std;



bool used[100010];

int dp[100010];

vector<pair<int,int> > g[100010];

bool flag;



void dfs(int x) {

  // cout << "x:" << x << endl;

  used[x] = true;

  for(pair<int,int> i: g[x]) {

    // cout << "i:" << i.first << endl;

    if(!used[i.first]) {

      dp[i.first] = dp[x] + i.second;

      // cout << "dp:" << dp[i.first] << endl;

      if(dp[i.first] > 1e9) {

        flag = false;

        break;

      }

      dfs(i.first);

    } else {

      if(dp[i.first] != dp[x] + i.second) {

        flag = false;

        break;

      }

    }

  }

}



vector<int> G[100010];

int h[100010];

int main(void)

{

  int n, m;

  cin >> n >> m;

  for(int i;i<m;i++) {

    int l, r, d;

    cin >> l >> r >> d;

    l--, r--;

    g[l].push_back({r, d});

    G[l].push_back(r);

    h[r]++;

  }



  int v = n;

  stack<int> st;



  for(int i=0;i<n;i++) if(h[i] == 0) st.push(i);



  vector<int> ans;

  while(st.size()) {

    int i = st.top(); st.pop();

    ans.push_back(i);

    for(auto& j: G[i]) {

      h[j]--;

      if(h[j] == 0) st.push(j);

    }

  }



  if(ans.size() != n) {

    cout << "No" << endl;

    return 0;

  }



  for(int i=0;i<n;i++){

    if(!used[ans[i]]) {

      flag = true;

      dp[ans[i]] = 0;

      dfs(ans[i]);

      if(!flag) {

        cout << "No" << endl;

        return 0;

      }

    }

  }

  cout << "Yes" << endl;



  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 6.347612543840753x):
#include <iostream>

#include <vector>



using namespace std;



class WeightUnionFind{

    public:

        vector<int> par, diff_w, rank;



        WeightUnionFind(int N){

            par.resize(N,0);

            diff_w.resize(N,0);

            rank.resize(N,0);

            for(int i=0;i<N;i++){

                par[i] = i;

            }

        }



        int root(int x){

            if(x == par[x]){

                return par[x];

            }else{

                int r = root(par[x]);

                diff_w[x] += diff_w[par[x]];

                return par[x] = r;

            }

        }



        void unite(int x, int y, int w){

            w += weight(x); w -= weight(y);

            x = root(x);

            y = root(y);

            if(x==y) return;

            else{

                if(rank[x] < rank[y]){ swap(x,y); w = -w; }

                if(rank[x] == rank[y]) rank[y]++;

                par[y] = x;

                diff_w[y] = w;

            }

        }



        int weight(int x){

            root(x);

            return diff_w[x];

        }

        

        int diff(int x, int y){

            return weight(y) - weight(x);

        }

        bool same(int x, int y){

            return root(x) == root(y);

        }

};



int main(){

    int N, M;

    cin >> N >> M;

    int l,r,d;

    WeightUnionFind wuf = WeightUnionFind(N);



    for(int i=0;i<M;i++){

        cin >> l >> r >> d;

        l--; r--;

        if(wuf.same(l,r)){

            if(wuf.diff(l,r) != d){

                cout << "No" << endl;

                return 0;

            }

        }else{

            wuf.unite(l,r,d);

        }

    }



    cout << "Yes" << endl;

    return 0;

}