// Original C++ solution (slower):
#include <bits/stdc++.h>



#define rep(i, n) for(int i = 0; i < n; i++)



using namespace std;

using ll = long long;

int mod = 1000000007;



int kakutei[100000];

vector<pair<int, int>> node[100000]; //iに対してnode[i].secondを足すとnode[i].firstに行ける



void dfs(int p, int s, vector<int>& vec){

    vec.push_back(s);

    rep(i, node[s].size()){

        int to = node[s][i].first;

        int dist = node[s][i].second;

        if(to != p && kakutei[to] == mod){

            kakutei[to] = kakutei[s]+dist;

            dfs(s, to, vec);

        }

    }

}



int main(void){

    rep(i, 100000) kakutei[i] = mod;

    int N, M; cin >> N >> M;

    rep(i, M){

        int a, b, d; cin >> a >> b >> d;

        node[a-1].push_back(make_pair(b-1, d));

        node[b-1].push_back(make_pair(a-1, -d));

    }

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

        vector<int> res;

        if(kakutei[i] == mod){

            kakutei[i] = 0;

            dfs(-1, i, res);



            //この時点でiを始点とするグラフ内のノードの値は確定している

            int minval = kakutei[i], maxval = kakutei[i];

            rep(j, res.size()){

                if(kakutei[res[j]] < minval) minval = kakutei[res[j]];

                if(kakutei[res[j]] > maxval) maxval = kakutei[res[j]];

            }

            if(minval < 0){

                rep(j, res.size()){

                    kakutei[res[j]] -= minval;

                }

            }

            if(maxval > 1000000000){

                int sabun = maxval-1000000000;

                rep(j, res.size()){

                    kakutei[res[j]] -= sabun;

                }

            }

        }

    }



    rep(i, N){

        if(kakutei[i] < 0 || kakutei[i] > 1000000000){

            cout <<  "No" << endl;

            return 0;

        }

    }



    rep(i, N){

        rep(j, node[i].size()){

            if(kakutei[i] + node[i][j].second != kakutei[node[i][j].first]){

                cout << "No" << endl;

                return 0;

            }

        }

    }

    cout << "Yes" << endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



#define rep(i, n) for(int i = 0; i < n; i++)

using namespace std;



typedef long long ll;



const int INF = 1 << 30;

const ll LLINF = 1LL << 62;



int mod = 1000000007;



struct edge{

    int to;

    ll cost;

};



vector<edge> nodes[100000];

int visited[100000] = {};

ll zahyou[100000];



void init(){

    rep(i, 100000) zahyou[i] = -1;

}



bool dfs(int p, int s){

    bool ret = true;

    visited[s] = true;

    rep(i, nodes[s].size()){

        int to = nodes[s][i].to;

        ll cost = nodes[s][i].cost;

        if(to == p) continue;

        if(visited[to]){

            if(zahyou[to] != zahyou[s] + cost) ret = false;

        }

        else{

            zahyou[to] = zahyou[s] + cost;

            ret &= dfs(s, to);

        }

    }

    return ret;

}



int main(void){

    ios::sync_with_stdio(false);

    cin.tie(nullptr);

    int N, M; cin >> N >> M;

    rep(i, M){

        int l, r; cin >> l >> r;

        l--; r--;

        ll d; cin >> d;

        edge e;

        e.to = r; e.cost = d;

        nodes[l].push_back(e);

        e.to = l; e.cost = -d;

        nodes[r].push_back(e);

    }



    bool res = true;

    rep(i, N){

        if(!visited[i]){

            zahyou[i] = 0;

            res &= dfs(-1, i);

        }

    }

    if(res) cout << "Yes" << endl;

    else cout << "No" << endl;

    return 0;

}

// Fastest known solution for this problem: