#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>

#define INF 20000000000
using namespace std;

struct edge{int to, cost; };
typedef pair<int,int> P;

int N;
int M;
int L[100000];
int R[100000];
int D[100000];

vector<edge> G[100001];
long long d[100001];
bool changed[100001];


void bfs(int s){
	priority_queue<P, vector<P>, greater<P> > que;
	if(d[s]==INF) d[s] = 0;
	changed[s] = true;
	que.push(P(0,s));
	while(!que.empty()){
		P p = que.top(); que.pop();
		int v = p.second;
		if(d[v]<p.first) continue;
		for(int i=0;i<G[v].size();i++){
			struct edge e = G[v][i];
			if(d[e.to] == INF){
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to],e.to));
				changed[d.to] = true;
				//printf("e.to:%d d[e.to]%lld\n",e.to,d[e.to]);
			}
		}
	}
}


int main(){
	scanf("%d %d", &N, &M);
	for(int i=0;i<M;i++) scanf("%d %d %d", &L[i],&R[i],&D[i]);
	for(int i=0;i<M;i++){
		struct edge e;
		e.cost = D[i];
		e.to = R[i];
		G[L[i]].push_back(e);
		//
		e.cost = -D[i];
		e.to = L[i];
		G[R[i]].push_back(e);
		//
	}
	for(int i=0;i<N+1;i++) changed[i] = false;
	fill(d,d+100001,INF);

	for(int i=0;i<M;i++){
		if(changed[L[i]]==false) bfs(L[i]);
	}


	for(int i=1;i<N+1;i++){
		//printf("%lld ",d[i]);
	}

	for(int i=0;i<M;i++){
		if(d[R[i]] - d[L[i]] != D[i]){
			printf("No\n");
			return 0;
		}
	}

	printf("Yes\n");
	return 0;
}
