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

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <climits>

#include <cstring>

#include <string>

#include <vector>

#include <list>

#include <queue>

#include <stack>

#include <map>

#include <set>

#include <bitset>

#include <algorithm>

#include <functional>

#include <iomanip>

using namespace std;



#define LL long long

const int maxn = 100000 + 100;

struct Node {

    int pos;

    int dis;

    Node() {}

    Node(int p, int d) {

        pos = p;

        dis = d;

    }

};

int n, m, u, v, d;

bool flag;

int num[maxn], fa[maxn];

bool vis[maxn];

vector<Node> G[maxn];

queue<Node> que;



void Init() {

    flag = true;

    memset(vis, 0, sizeof(bool) * (n + 1));

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

        G[i].clear();

    }

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

        fa[i] = i;

    }

}



int Find(int x) {

    return (x == fa[x]? x: fa[x] = Find(fa[x]));

}



void unit(int x, int y) {

    int xx = Find(x);

    int yy = Find(y);

    fa[xx] = yy;

}



bool bfs(int x) {

    num[x] = 0;

    vis[x] = true;

    while(!que.empty()) {

        que.pop();

    }

    que.push(Node(x, 0));

    while(!que.empty()) {

        Node tmp = que.front();

        que.pop();

        int len = G[tmp.pos].size();

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

            int pos = G[tmp.pos][i].pos;

            int d = G[tmp.pos][i].dis;

            if(!vis[pos]) {

                vis[pos] = true;

                num[pos] = tmp.dis + d;

                que.push(Node(pos, num[pos]));

            } else if(num[pos] != tmp.dis + d) {

                return false;

            }

        }

    }

    return true;

}



int main() {

    #ifdef LOCAL

        freopen("test.txt", "r", stdin);

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

    #endif // LOCAL

    ios::sync_with_stdio(false);



    while(scanf("%d%d", &n, &m) != EOF) {

        Init();

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

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

            G[u].push_back(Node(v, d));

            G[v].push_back(Node(u, -d));

            unit(v, u);

        }

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

            if(!vis[Find(i)]) {

                if(!bfs(Find(i))) {

                    flag = false;

                    break;

                }

            }

        }

        if(flag) {

            printf("Yes\n");

        } else {

            printf("No\n");

        }

    }



    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 2.5654181553042643x):
#include<stdio.h>

#include<string.h>

#include<iostream>

#include<malloc.h>

#include<math.h>

#include<algorithm>



using namespace std;



const int maxn = 1e5+100;

int n,m,tag,f[maxn],dis[maxn];



int getfa(int x)

{

    if (f[x]==x) return x;

    int fx = getfa(f[x]);

    dis[x] += dis[f[x]];

    f[x] = fx;

    return f[x];

}



int main()

{

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

    tag = 1;

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

    for (int i=1;i<=n;i++) f[i] = i;

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

    {

        int x,y,d;

        scanf("%d %d %d",&x,&y,&d);

        int fx = getfa(x);

        int fy = getfa(y);

        if (fx == fy)

        {

            if (dis[y] != dis[x]+d) tag = 0;

        }

        else

        {

            f[fy] = fx;

            dis[fy] = dis[x]+d-dis[y];

        }

    }

    if (tag) printf("Yes");

    else

        printf("No");

    return 0;

}