// 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.2688959848362595x):
#include <bits/stdc++.h>

#define R register int

using namespace std;



const int N = 1e5 + 5, M = 2e5 + 5;



struct Graph

{

    int head[N], to[M << 1], next[M << 1], v[M << 1], cnt;



    inline void add_edge(int x, int y, int v_)

    {

        to[++cnt] = y, next[cnt] = head[x], v[cnt] = v_, head[x] = cnt;

    }

} e;

int n, m;



queue<int> q;

int dis[N];

bool vis[N];

bool spfa(int st)

{

    vis[st] = 1, dis[st] = 0, q.push(st);

    while (!q.empty())

    {

        int x = q.front();

        q.pop();

        for (R i = e.head[x]; i; i = e.next[i])

        {

            int u = e.to[i];

            if (vis[u])

            {

                if (dis[x] + e.v[i] != dis[u]) return false;

            }

            else dis[u] = min(dis[u], dis[x] + e.v[i]), vis[u] = 1, q.push(u);

        }

    }

    return true;

}



int main()

{

    memset(dis, 0x3f, sizeof dis);

    ios::sync_with_stdio(false);

    cin >> n >> m;

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

    {

        int x, y, v;

        cin >> x >> y >> v;

        e.add_edge(x, y, v), e.add_edge(y, x, -v);

    }

    bool flag = true;

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

        if (!vis[i] && !spfa(i)) { flag = false; break; }

    if (flag) cout << "Yes\n";

    else cout << "No\n";

    return 0;

}