// Original C++ solution (slower):
    //It is made by Awson on 2018.1.28

    #include <set>

    #include <map>

    #include <cmath>

    #include <ctime>

    #include <queue>

    #include <stack>

    #include <cstdio>

    #include <string>

    #include <vector>

    #include <complex>

    #include <cstdlib>

    #include <cstring>

    #include <iostream>

    #include <algorithm>

    #define LL long long

    #define dob complex<double>

    #define Abs(a) ((a) < 0 ? (-(a)) : (a))

    #define Max(a, b) ((a) > (b) ? (a) : (b))

    #define Min(a, b) ((a) < (b) ? (a) : (b))

    #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))

    #define writeln(x) (write(x), putchar('\n'))

    #define lowbit(x) ((x)&(-(x)))

    using namespace std;

    const int N = 100000;

    const int M = 200000;

    void read(int &x) {

        char ch; bool flag = 0;

        for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());

        for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());

        x *= 1-2*flag;

    }

    void write(int x) {

        if (x > 9) write(x/10);

        putchar(x%10+48);

    }

     

    int n, m, path[N+5], tot, u, v, c, flag;

    int dist[N+5], vis[N+5];

    struct tt {int to, cost, next; }edge[(M<<1)+5];

    void add(int u, int v, int c) {edge[++tot].to = v, edge[tot].cost = c, edge[tot].next = path[u], path[u] = tot; }

     

    bool dfs(int o) {

        vis[o] = 1;

        for (int i = path[o]; i; i = edge[i].next)

    	if (dist[edge[i].to] > dist[o]+edge[i].cost) {

    	    if (vis[edge[i].to]) return true;

    	    dist[edge[i].to] = dist[o]+edge[i].cost;

    	    if (dfs(edge[i].to)) return true;

    	}

        vis[o] = 0; return false;

    }

    void work() {

        read(n), read(m);

        for (int i = 1; i <= m; i++) {read(u), read(v), read(c); add(u, v, c), add(v, u, -c); }

        for (int i = 1; i <= n; i++) if (dfs(i)) {flag = 1; break; }

        if (flag) puts("No");

        else puts("Yes");

    }

    int main() {

        work(); return 0;

    }

// Optimized solution to the same problem (faster):
#include<cstdio>

#include<algorithm>

#define int long long

using namespace std;

const int maxN=1e6 + 100;

struct Node

{

	int to,value,next;

}edge[maxN*2+1];

int n,m,head[maxN+1],tot,dis[maxN+1];

bool col[maxN+1];

int maxT=-1e15,minT=1e15,ans=-1e15;

void add(int x,int y,int t)

{

	tot++;

	edge[tot].to=y;

	edge[tot].value=t;

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

	head[x]=tot;

}

bool dfs(int x)

{

	maxT=max(maxT,dis[x]);

	minT=min(minT,dis[x]);

	bool flag=true;

	col[x]=true;

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

		if(!col[edge[i].to]) dis[edge[i].to]=dis[x]+edge[i].value,flag=(flag&&dfs(edge[i].to));

		else if(dis[x]+edge[i].value!=dis[edge[i].to]) flag=false;

	return flag;

}

#undef int

int main()

#define int long long

{

//	freopen("line.in","r",stdin);

//	freopen("line.out","w",stdout);

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

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

	{

		int x,y,t;

		scanf("%lld%lld%lld",&x,&y,&t);

		add(x,y,t); add(y,x,-t);

	}

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

		if(!col[i])

		{

			maxT=-1e18,minT=1e18;

			if(!dfs(i))

			{

				printf("No");

				return 0;

			}

			ans=max(ans,maxT-minT);

		}

	printf("Yes");

	fclose(stdin);

	fclose(stdout);

	return 0;

}

// Fastest known solution for this problem: