//a+mod-b %mod
//a^x first not1 buta notf+f butf*f
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <math.h>
#include <iomanip>
#include <limits>
#include <queue>
using namespace std;
#define MOD (long long int)(1e9+7)
#define ll long long int
#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define REPS(i,n) for(int i=1; i<=(int)(n); i++)
//#define ARRAY(type,n) (type *)malloc(sizeof(type)*n)
template<typename T>
T* ARRAY(int n){
	(T*)malloc(sizeof(T)*n);
}
template<typename T>
T** ARRAY2(int m,int n){
	T** type = (T**)malloc(sizeof(T*)*m);
	for(int i=0;i<m;i++){
		type[i]=(T*)malloc(sizeof(T)*n);
	}
	return type;
}
class llm{
public:
llm(ll value){this->value = (ll)value;}
ll value;
llm operator + (llm obj){return llm((this->value + (ll)(obj.value))%MOD);}
llm operator + (ll obj){return llm((this->value + obj)%MOD);}
llm operator - (llm obj){return llm(((this->value + MOD - (ll)(obj.value)))%MOD);}
llm operator - (ll obj){return llm(((this->value + MOD - obj))%MOD);}
llm operator * (llm obj){return llm((this->value * (ll)(obj.value))%MOD);}
llm operator * (ll obj){return llm((this->value * obj)%MOD);}
llm operator / (llm obj){return llm(this->value / (ll)(obj.value));}
llm operator / (ll obj){return llm(this->value / obj);}
llm operator % (llm obj){return llm(this->value % (ll)(obj.value));}
llm operator % (ll obj){return llm(this->value % obj);}};
ostream& operator<<(ostream& os, llm l){os << l.value;return os;} 
llm operator+(ll a,llm l){return llm((a + l.value)%MOD);} 
llm operator*(ll a,llm l){return llm((a * l.value)%MOD);}

/*
typedef struct{
	int l;
	int r;
	int d;

	bool operator<( const data_t& right ) const {
        return l == right.num ? str < right.str : num < right.num;
    }
}INPUT;*/

struct List{
	int node;
	int d;//right = +
	List* last;
	List* next;
};

void addlist(struct List array[100001], int l,int r,int d){
	array[l].last->next = (struct List*)malloc(sizeof(struct List));
	array[l].last->next->node = r;
	array[l].last->next->d = d;
	array[l].last->next->next = NULL;
	array[l].last=array[l].last->next;
	/*}else{
		int hoge;
		hoge=l;
		l=r;
		r=hoge;
		array[l].last->next = (struct List*)malloc(sizeof(struct List));
		array[l].last->next->node = r;
		array[l].last->next->d = -d;
		array[l].last->next->next = NULL;
		array[l].last=array[l].last->next;
	}*/
}

bool dfs(struct List array[100001], int man[100001],int n){
	queue<int> que;
	struct List *see = array+n;
	bool b = true;

	while(see->next!=NULL){
		see=see->next;
		if(array[see->node].node != -1){
			que.push(see->node);
		}
		if(man[see->node]==-1){
			man[see->node] = man[array[n].node] + see->d;
		}else{
			if(man[see->node] == man[(array+n)->node] + see->d){
				b = true;
			}else{
				return false;
			}
		}
		
	}

	(array+n)->node = -1;

	while(!que.empty()){		
		int q = que.front();
		if((array+q)->node!=-1){
			b = b&&dfs(array,man,q);
		}
		que.pop();

	}
	
	return b;
}


int main(void){
	int n,m;
	cin>>n>>m;
	int man[100001];
	struct List* array = (struct List*)malloc(sizeof(struct List)*100001);

	for(int i=1;i<=100000;i++){
		man[i]=-1;
		
	}

	for(int i=1;i<100001;i++){
		array[i];
		////////////hogeeeeeeeeeeeeeeee
		array[i].node = i;
		array[i].d = 0;
		array[i].last = &(array[i]);
		array[i].next = NULL;
	}


	int l,r,d;
	for(int i=0;i<m;i++){
		cin>>l>>r>>d;
		addlist(array,l,r,d);
		addlist(array,r,l,-d);
		
	}

	bool b;
	for(int i=1;i<=n;i++){
		if(array[i].node!=-1){
			man[i]=0;
			b = dfs(array,man,i);
			if(!b){
				cout<<"No"<<endl;
				return 0;
			}
		}
	}

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


Measured memory_bytes: 90240