// Slower C++ solution:
#include <cstdio>

#include <iostream>

#include <algorithm>

#include <cstring>

#include <queue>



using namespace std;



struct edge

{

    int v,w,nxt;

}e[400050];



int head[100050],ecnt;



void adde(int u,int v,int w)

{

    e[++ecnt].v = v;

    e[ecnt].w = w;

    e[ecnt].nxt = head[u];

    head[u] = ecnt;

}



int N,M;

int l[200050],r[200050];

int d[200050];

long long dist[100005];

queue<int> que;

bool vis[100050],inq[100050];



bool spfa(int st)

{

    que.push(st);

    inq[st] = true;

    dist[st] = 0;

    long long curmax = 0,curmin = 0;

    while(!que.empty())

    {

        int u = que.front();

        que.pop();

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

        {

            int v = e[i].v;

            if(dist[v] == 12345678987654321)

            {

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

                curmax = max(curmax,dist[v]);

                curmin = min(curmin,dist[v]);

                if(curmax - curmin > 1000000000)

                    return false;

                vis[v] = 1;

                if(!inq[v])

                    que.push(v);

            }

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

                return false;

        }

        inq[u] = false;

    }

    return true;

}



int main()

{

    for(int i = 1;i <= 100000; ++ i)

        dist[i] = 12345678987654321;

    scanf("%d%d",&N,&M);

    for(int i = 1;i <= M; ++ i)

    {

        scanf("%d%d%d",&l[i],&r[i],&d[i]);

        adde(l[i],r[i],d[i]);

        adde(r[i],l[i],-d[i]);

    }

    for(int i = 1;i <= N; ++ i)

    {

        if(!vis[i])

        {

            vis[i] = 1;bool l = spfa(i);

            if(!l)

            {

                printf("No\n");

                return 0;

            }

        }

    }

    printf("Yes\n");

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.2846659782571788x):
#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");

}