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

#include <algorithm>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <queue>

using namespace std;

#define fors(i,a,b) for(int i=(a);i<=(b);++i)

typedef long long ll;

const int Size=1<<18;

inline char getch(){

    static char buf[Size],*p1=buf,*p2=buf;

    return p1==p2 && (p2=(p1=buf)+fread(buf,1,Size,stdin),p1==p2) ? EOF : *p1++;

}

int read(){

    int s=0,f=1;

    char c=getch();

    while(c>'9' || c<'0'){if(c=='-') f=-1; c=getch();}

    while(c<='9' && c>='0'){s=(s<<1)+(s<<3)+c-'0';c=getch();}

    return s*f;

}



const int maxn=100007;

const long long inf=12345678987654321;

struct node

{

    int to,next,val;

}edge[maxn<<2];

int head[maxn],tot,n,m,vis[maxn],visq[maxn];

ll dis[maxn];



void add(int x,int y,int w){

    edge[++tot].to=y;

    edge[tot].next=head[x];

    head[x]=tot;

    edge[tot].val=w;

}



queue<int> q;

int spfa(int s){

    q.push(s);

    dis[s]=0,vis[s]=1;

    ll maxs=0,mins=0;

    while(!q.empty()){

        int u=q.front();

        q.pop();

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

            int to=edge[i].to;

            if(dis[to]==inf){

                dis[to]=dis[u]+edge[i].val;

                maxs=max(maxs,dis[to]);

                mins=min(mins,dis[to]);

                if(maxs-mins>10000000000) return 0;

                visq[to]=1;

                if(!vis[to])

                    q.push(to);

            }

            else if(dis[to]!=dis[u]+edge[i].val) return 0;

        }

        vis[u]=0;

    }

    return 1;

}

int main(int argc, char const *argv[])

{

    fill(dis,dis+maxn-1,inf);

    n=read(),m=read();

    fors(i,1,m){

        int l=read(),r=read(),w=read();

        add(l,r,w);

        add(r,l,-w);

    }

    fors(i,1,n)

        if(!visq[i]){

            visq[i]=1;

            int flag=spfa(i);

            if(!flag){

                printf("No\n");

                return 0;

            }

        }

    printf("Yes\n");

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1232366149027768x):
//people on a line

#include<cstdio>

#include<cstring>

#include<string>

#include<algorithm>

#include<iostream>

#include<queue>

using std::queue;

using std::sort;

const int maxn=100010;

const int maxm=400050;

const long long inf=9999999999;

long long dis[maxn];

bool vis[maxn];

int head[maxn]; int cnt=0;

bool inq[maxn];

inline void init(int n) {

	memset(head,-1,sizeof(head));

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

		dis[i]=inf;

	}

	memset(vis,false,sizeof(vis));

	memset(inq,false,sizeof(inq));

}

struct zmm{

	int to,next;

	int dis;

}a[maxm];

inline void add(int from,int to,int dis) {

	a[++cnt].to=to;

	a[cnt].dis=dis;

	a[cnt].next=head[from];

	head[from]=cnt;

	return;

}

queue<int> q;

bool spfa(int s) {



	//while(!q.empty()) q.pop();

	inq[s]=true; q.push(s);

	dis[s]=0;

	while(!q.empty()) {

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

		inq[u]=false;

		int v;

		for(int i=head[u];i!=-1;i=a[i].next){

			v=a[i].to;

			if(dis[v]==inf) {

				dis[v]=dis[u]+a[i].dis;

				vis[v]=true;

				if(!inq[v]) {

					q.push(v);

					inq[v]=true;

				}

			}

			else if(dis[v]!=dis[u]+a[i].dis) {

				return false;

				}

		}

	}

	return true;

}

int main()

{

	int n,m;

	scanf("%d%d",&n,&m);

	int u,v,w;

	init(n);

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

		scanf("%d%d%d",&u,&v,&w);

		add(u,v,w);

		add(v,u,-w);

	}

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

		if(!vis[i]) {

			vis[i]=true;

			if(!spfa(i)) {

				printf("No");

				return 0;

			}

		}

	}

	printf("Yes");

	return 0;

}