#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define drep(x,a,b) for(int x=a;x>=b;x--)
#define rush() int T;scanf("%d",&T);while(T--)
#define wash(x,y) memset(x,y,sizeof(x));

const int maxn=1e5+5;
int fa[maxn],dd[maxn],n,m;

//并查集初始化
//！！！注意i的起点
void init(){
	for(int i=1;i<=n;i++){
		fa[i]=i;
		dd[i]=0;
	}
}
//并查集路径压缩寻找根节点
int find(int x){
	if(x==fa[x]) return x;
	else{
		int tmp=fa[x];
		fa[x]=find(tmp);
		dd[x]=dd[x]+dd[tmp];
		return fa[x];
	}
}
//并查集合并
bool merge(int x,int y,int d){
	int fx=find(x),fy=find(y);
	if(fx==fy) return (dd[y]-dd[x]==d);
	else{
		fa[fx]=fy;
		dd[fx]=dd[y]-dd[x]-d;
		return true;
	}
}

int main(){
	int l,r,d;
	bool flag=true;
	scanf("%d%d",&n,&m);
	init();
	rep(i,1,m){
		scanf("%d%d%d",&l,&r,&d);
		if(flag&&!merge(l,r,d)) flag=false;
	}
	printf(flag?"Yes":"No");
}