// 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: 3.5625836383226424x):
#include <cstdio>

#include <cstring>

#include <iostream>

using namespace std;

#define maxn 200000 + 10

int father[maxn];

int val[maxn];

int Find(int x)

{

    if (x == father[x])

        return x;

    int temp = father[x];

    father[x] = Find(father[x]);

    val[x] += val[temp];

    return father[x];

}

int n, m;

int main()

{

    while (~scanf("%d %d", &n, &m))

    {

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

        {

            father[i] = i;

            val[i] = 0;

        }

        int ans = 0;

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

        {

            int u, v, w;

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

//            u -= 1;

            int ru = Find(u), rv = Find(v);

            if (ru == rv)

            {

                if (val[u] + w != val[v])

                {

                    cout << "No" << endl;

                    return 0;

                }

            }

            else

            {

                father[rv] = ru;

                val[rv] = val[u] - val[v] + w;

            }

        }

        cout << "Yes" << endl;

    }

    return 0;

}