#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<cmath>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<numeric>
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; }
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;
int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};

#include <bits/stdc++.h>

template<class Abel> struct PotentialUnionFind
{
    std::vector<int> par; // parent node
    std::vector<int> rank; // tree height
    std::vector<Abel> diff_weight; // the weight of the edge between child and parent.
    
    PotentialUnionFind(int n=1,Abel SUM_UNITY = 0) // constructor
    {
        init(n,SUM_UNITY);
    }

    void init(int n=1, Abel SUM_UNITY = 0) // initialize
    {
        par.resize(n);rank.resize(n);diff_weight.resize(n);
        // All vertices are root and height of 0 in the beginning.
        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) // judging of whether x and y belong to same group.
    {
        return root(x) == root(y);
    }

    bool merge(int x, int y, Abel w) // merge the group to which x belongs and the group to which group y belongs. 
    {                        // merge the group of y into the group of x. x <--- y
        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()
{

    int n,m;
    cin >> n >> m;
    // PotentialUnionFind<int> putree = PotentialUnionFind<int>(n,0);
    PotentialUnionFind<int> uf(n);

    for (int i=0; i<m; ++i)
    {
        int left,right,dist;
        cin >> left >> right >> dist;
        --left; --right;
        if(uf.isSame(left,right))// If they are already in the same group,
        {
            int diff = uf.diff(left,right);
            if(diff != dist)
            {
                cout << "No" << endl;
                return 0;
            }
        }
        else
        {
            uf.merge(left,right,dist);
        }
        
    }

    cout << "Yes" << endl;
    return 0;
}


        // if(putree.merge(left,right,dist)) 
        // {
        //     if(abs(putree.diff_weight[left] - putree.diff_weight[right])!= dist)
        //     {
        //         cout << "No" << endl;
        //         return 0;
        //     }  
        // }

Measured memory_bytes: 1408