// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> P;



const int MAX_N = 1e5 + 1;

const int MAX_M = 2 * 1e5 + 2;



bool is_checked[MAX_N];

int parent[MAX_N], dist[MAX_N];

vector<P> graph[MAX_N];



bool bfs(int root) {

    queue<P> Q;

    Q.push(P(root, 0));

    while (!Q.empty()) {

        P now = Q.front();

        Q.pop();

        int node = now.first, cost = now.second;

        if (dist[node] == 0) dist[node] = cost;

        else if (dist[node] != cost) {

            return false;

        }

        if (is_checked[node]) continue;

        

        for (int i = 0; i < graph[node].size(); i++) {

            if (is_checked[graph[node][i].first]) {

                if (dist[graph[node][i].first] != graph[node][i].second + cost) {

                    return false;

                }

            }

            else Q.push(P(graph[node][i].first, graph[node][i].second + cost));

        }

        is_checked[node] = true;

    }

    return true;

}



int main() {

    int N, M, L, R, D;

    cin >> N >> M;

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

        cin >> L >> R >> D;

        parent[R] = L;

        graph[L].push_back(P(R, D));

    }

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

        if (parent[i] == 0 && !is_checked[i]) {

            if (!bfs(i)) {

                cout << "No" << endl;

                return 0;

            }

        }

    }

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

        if (!is_checked[i]) {

            cout << "No" << endl;

            return 0;

        }

    }

    cout << "Yes" << endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.460432368378908x):
#include <bits/stdc++.h>

using namespace std;

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

typedef long long ll;

typedef unsigned long long ull;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }

template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }



/* attention

    long longのシフト演算には気をつけよう

    タイポした時のデバッグが死ぬほどきつくなるので変数名は最低3字くらい使った方がいいかも

    sizeは(int)とキャストしよう

    ごちゃごちゃ場合分けを考える前に全探索は考えましたか？

*/



const ll mod = 1e9+7;



void chmod(ll &M){

    if(M >= mod) M %= mod;

    else if(M < 0){

        M += (abs(M)/mod + 1)*mod;

        M %= mod;

    }

}



ll modpow(ll x, ll n){

    if(n == 0) return 1;



    ll res = modpow(x, n/2);

    if(n%2 == 0) return res*res%mod;

    else return res*res%mod*x%mod;

}



ll power(ll x, ll n){

    if(n == 0) return 1;



    ll res = power(x, n/2);

    if(n%2 == 0) return res*res;

    else return res*res*x;

}



int getl(int i, int N) { return i==0? N-1:i-1; };

int getr(int i, int N) { return i==N-1? 0:i+1; };



/* <--------------------------------------------> */





template<class Abel> struct UnionFind {

    vector<int> par;

    vector<int> rank;

    vector<Abel> diff_weight; //親との差分



    UnionFind(int n = 1, Abel SUM_UNITY = 0){

        init(n, SUM_UNITY);

    }



    void init(int n = 1, Abel SUM_UNITY = 0){

        par.resize(n); rank.resize(n); diff_weight.resize(n);

        for(int i=0; i<n; i++) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;

    }



    int root(int x){

        if(par[x] == x){

            return x;

        }

        else{

            int r = root(par[x]);

            diff_weight[x] += diff_weight[par[x]];

            return par[x] = r;

        }

    }



    Abel weight(int x){

        root(x);

        return diff_weight[x];

    }



    bool issame(int x, int y){

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

    }



    // weight[y] - weight[x] = w になるようにマージする（x yがそれぞれの木でrootになってるわけではないことに注意）

    bool merge(int x, int y, Abel w){

        // xとyそれぞれについて、rootとの重み差分を補正

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

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

        if(x == y) return false;

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

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

        par[y] = x;

        diff_weight[y] = w;

        return true;

    }



    Abel diff(int x, int y){

        return weight(y) - weight(x);

    }

};



int main(){

    cin.tie(0);

    ios::sync_with_stdio(false);



    int n, m; cin >> n >> m;

    UnionFind<int> uni(n);



    rep(i, m){

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

        --l, --r;

        if(uni.issame(l, r) && uni.diff(l, r) != d){

            cout << "No\n";

            return 0;

        }

        else if(!uni.issame(l, r)){

            uni.merge(l, r, d);

        }

    }

    cout << "Yes\n";



	return 0;

}