// Slower C++ solution:
#ifndef chafen

#define chafen



# include <cstdio>

# include <iostream>

# include <cstring>

# include <queue>

# pragma GCC optimize(2)

# define N 300000

# define INF 0x7f7f7f7f //0x7fffffff

# define _cin std::ios::sync_with_stdio(false)

# define rg register

# define il inline

struct edge{

    int next;

    int to;

    int w;

}e[(N+1)<<1];

int head[N+1];

int book[N+1];

int vis[N+1];

int dis[N+1];

int n,m;

using namespace std;

//template <class A> il bool SPFA(A s);

bool SPFA(int s);

int main()

{

    _cin;

    rg int edge_sum=0;

    rg int u,v,w;

    cin>>n>>m;

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

        cin>>u>>v>>w;

        //edge_sum++;

        e[i].next=head[u];

        e[i].to=v;

        e[i].w=w;

        head[u]=i;

        

        //edge_sum++;

        e[i+m].next=head[v];

        e[i+m].to=u;

        e[i+m].w=-w;

        head[v]=i+m;

    }

    memset(dis,0x7f,sizeof(dis));

    memset(vis,0,sizeof(vis));

    memset(book,0,sizeof(book));

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

        if(!vis[i]){

            vis[i]=1;

            if(!SPFA(i)){

                cout<<"No"<<endl;

                return 0;

            }

        }

    }

    cout<<"Yes"<<endl;

    return 0;

}

//template <class A> il bool SPFA(A s)

il bool SPFA(int s)

{

    queue <int> q;

    dis[s]=0;

    q.push(s);book[s]=1;

    while(q.size()>0){

        rg int k=q.front();q.pop();

        book[k]=0;

        for(rg int i = head[k];i;i=e[i].next){

            rg int tt=e[i].to;

            if(dis[k]<INF && dis[tt]<INF && dis[tt]!=dis[k]+e[i].w) return false;

			else if(dis[k]<INF && dis[tt] == INF){

                dis[tt]=dis[k]+e[i].w;

                if(book[tt] == false) {q.push(tt);book[tt]=1;}

                vis[tt]=1;

            }

        }

    }

    return true;

}



#endif

// Faster C++ solution for the same problem (measured speedup: 2.605947007493144x):
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <queue>

#include <vector>

#include <cmath>

#define LL long long

using namespace std;

const int MOD=1e9+7;

const int INF=0x3f3f3f3f;

const int M=200100;

const int N=100100;

inline void read(int &x){

	x=0;int mm=1; char ch=getchar();

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

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

	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

	x=x*mm;

}

inline void read(LL &x){

	x=0;LL mm=1; char ch=getchar();

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

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

	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();

	x=x*mm;

}

struct Edge{

	int nxt;

	int v,w;

}edge[M<<2];

int head[N],tot;

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

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

	edge[tot].v=v;

	edge[tot].w=w;

	head[u]=tot;

}

int n,m;

int dist[N];

bool visited[N],inque[N];

queue <int> q;

bool SPFA(int beginn){

	visited[beginn]=true;

	inque[beginn]=true;

	dist[beginn]=0;

	q.push(beginn);

	int maxx=0,minn=0;

	while(!q.empty()){

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

		inque[u]=false;

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

			Edge &e=edge[i];

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

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

					return false;

				}

			}else{

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

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

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

				if(maxx-minn>INF) return false;

				visited[e.v]=true;

				if(!inque[e.v]){

					inque[e.v]=true;

					q.push(e.v);

				}

			}

		}

	}

	return true;

}

int main(){

	read(n),read(m);

	memset(head,0,sizeof(head));

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

		int u,v,w;

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

		add(u,v,w);

		add(v,u,-w);

	}

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

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

		if(!visited[i])

			if(!SPFA(i)){

				printf("No");

				return 0;

			}

	}

	printf("Yes");

	return 0;

}