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

using namespace std;

inline void fff(){

	freopen("line.in","r",stdin);

	freopen("line.out","w",stdout);

}

const int N=1e5+10;

const int INF=0x3f3f3f3f;

inline int read(){

	int x=0,m=1;char ch=getchar();

	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();

	if(ch=='-') ch=getchar(),m=-1;

	while(ch<='9'&&ch>='0') 

		x=x*10+ch-'0',ch=getchar();

	return x*m;

}

int n,m;

struct Edge{

	int nxt;

	int to,w;

}edge[N<<2];

int head[N],tot=0;

inline void add(int u,int v,int w){

	edge[++tot].nxt=head[u];

	edge[tot].to=v;

	edge[tot].w=w;

	head[u]=tot;

}

bool visited[N];

int dist[N],ans,minn,maxx;

queue<int> q;

inline bool SPFA(int str){

	

	q.push(str);

	if(m) minn=INF,maxx=0;

	dist[str]=0;visited[str]=true;

	while(!q.empty()){

		int u=q.front();q.pop();

		visited[u]=false;

		for(int i=head[u];i;i=edge[i].nxt){

			Edge e=edge[i];

			if(dist[e.to]<INF){

				if(dist[e.to]!=e.w+dist[u]){

					return false;

				}

				minn=min(minn,dist[e.to]);

				maxx=max(maxx,dist[e.to]);

			}else{

				dist[e.to]=dist[u]+e.w;

				minn=min(minn,dist[e.to]);

				maxx=max(maxx,dist[e.to]);

				if(!visited[e.to]){

					visited[e.to]=true;

					q.push(e.to);

				}

			}

		}

	}

	ans=min(ans,maxx-minn);

	return true;

}

int main(){

//	fff();

	n=read();

	m=read();

	ans=INF;

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

		int u,v,w;

		u=read(),v=read(),w=read();

		add(u,v,w);

		add(v,u,-w);

	}

	memset(dist,INF,sizeof(dist));

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

		if(dist[i]<INF)  continue;

		if(!SPFA(i)){

			printf("No");

			return 0;

		}

	}

	printf("Yes");

}

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

using namespace std;



typedef long long lint;

typedef pair<int, int> P;

#define REP(i, x, n) for(lint i = x ; i < n ; i++)

#define rep(i, n) REP(i, 0, n)

#define repr(i, n) for(lint i = n - 1 ; i >= 0 ; i--)

#define SORT(c) sort((c).begin(), (c).end())



const int IINF = 1e9 + 10;

const lint LLINF = (lint)1e18 + 10;

const lint MOD = (lint)1e9 + 7;

const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

const int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};



struct weightedUnionFind{



    vector<int> par, rank, wei;



    void init(int n){

        par.resize(n);

        rank.resize(n, 0);

        wei.resize(n, 0);

        rep(i, n){

            par[i] = i;

        }

        return;

    }



    int root(int x){

        if(par[x] == x){

            return x;

        }else{

            int r = root(par[x]);

            wei[x] += wei[par[x]];

            return par[x] = r;

        }

    }



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

        w = -w;

        w += weight(x);

        w -= weight(y);

        int rx = root(x);

        int ry = root(y);

        if(rx == ry){

            return false;

        }

        if(rank[rx] < rank[ry]){

            swap(rx, ry);

            w = -w;

        }

        if(rank[rx] == rank[ry]){

            rank[rx]++;

        }

        par[ry] = rx;

        wei[ry] = w;

        return true;

    }



    bool same(int x, int y){

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

    }



    int weight(int x){

        root(x);

        return wei[x];

    }



    int diff(int x, int y){

        return weight(x) - weight(y);

    }



};



int main(){

    int n, m;

    cin >> n >> m;

    weightedUnionFind uf;

    uf.init(n);

    bool flag = true;

    rep(i, m){

        int l, r, d;

        cin >> l >> r >> d;

        l--;

        r--;

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

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

                flag = false;

                break;

            }

        }else{

            uf.unite(l, r, d);

        }

    }

    if(flag){

        cout << "Yes" << endl;

    }else{

        cout << "No" << endl;

    }

    return 0;

}