#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <cinttypes>
#include <string.h>
#include <bits/stdc++.h>

#define countof(a) (sizeof(a)/sizeof(*a))

#define vi vector<int>
#define vvi vector<vector<int> >
#define pi pair<int,int>
#define fi first
#define se second

#define FOR(var, to)          for (register s64 var = 0; var < (s64)to; var++)
#define FROMTO(var, from, to) for (register s64 var = from; var <= (s64)to; var++)

#define INIT(var) FOR(i,countof(var)) var[i] = 0
#define INPUT(var) FOR(i,countof(var)) var[i] = ri()

#define SORT(v) qsort(v,countof(v),sizeof(*v),int_less)
#define SORTT(v) qsort(v,countof(v),sizeof(*v),int_greater)

#define MOD 1000000007
#define INF (1 << 30)

typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;

using namespace std;

static inline int ri() {
  int a;
  scanf("%d", &a);
  return a;
}

static inline s64 rs64() {
  s64 a;
  scanf("%" SCNd64, &a);
  return a;
}

static inline void wi(int a) {
  printf("%d", a);
}

static inline void wu64(u64 a) {
  printf("%" PRIu64, a);
}

static inline void ws64(s64 a) {
  printf("%" PRId64, a);
}

int int_less(const void *a, const void *b) {
  return (*((const int*)a) - *((const int*)b));
}
int int_greater(const void *a, const void *b) {
  return (*((const int*)b) - *((const int*)a));
}

/* originally written by SugarDragon5 */
struct UnionFind{
    vi data;
    UnionFind(int size):data(size,-1){}
    bool unite(int x,int y){
        x=root(x);y=root(y);
        if(x!=y){
            if(data[y]<data[x])swap(x,y);
            data[x]+=data[y];data[y]=x;
        }
        return x!=y;
    }
    bool find(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0?x:data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};

vector<map<int,int> > v(100000);

void erase_one(int index) {
    if (v[index].size() == 1) {
        int i = v[index].begin()->first;
        v[index].erase(i);
        v[i].erase(index);
        erase_one(i);
    }
}

int main() {
    int n = ri();
    int m = ri();
    int l[m];
    int r[m];
    int d[m];
    FOR(i,m) l[i] = ri()-1, r[i] = ri()-1, d[i] = ri(),
        v[l[i]][r[i]]=d[i],
        v[r[i]][l[i]]=-d[i];
        
    FOR(i,n) erase_one(i);
    
    /*
    FOR(i,n) {
        cout << "i:" << i << endl;
        for (auto& i : v[i]) {
            cout << "fi:" << i.fi<<" se:"<<i.se << endl;
        }
        cout << endl;
    }*/
    
    UnionFind uni(n);
    FOR(i,n) {
        if (v[i].size()) {
            assert(v[i].size() != 1);
            for (auto& j : v[i])
                uni.unite(i,j.fi);
        }
    }
    // cout << "ok" << endl;
    vector<set<int> > vv(n);
    FOR(i,n) {
        if (uni.size(i) > 1) {
            vv[uni.root(i)].insert(i);
        }
    }
    
    
        bool res = true;
    int dat[n];
    FOR(i,n) dat[i] = INF;
    FOR(i,n) {
        if (vv[i].size()) {
            // cout << i << endl;
            // cout << i << ":" << vv[i].size() << endl;
            // vv[i]
            queue<int> q;
            q.push(i);
            dat[i] = 0;
            while(q.size()) {
                auto i = q.front(); q.pop();
                // cout << "size" << q.size() << "vsize" << v[i].size() << endl;
                for (auto& j : v[i]) {
                    if (!v[j.fi].size()) continue;
                    if (dat[j.fi] == INF) dat[j.fi] = dat[i]+j.se,q.push(j.fi);
                    else if (dat[j.fi] != dat[i]+j.se) {
                        res = false;
                        break;
                    }
                }
                vv[i].clear();
                if (!res) break;
            }
        }
        if (!res) break;
    }
    cout << (res?"Yes":"No") << endl;
 return 0;
}


Measured memory_bytes: 35200