#include <bits/stdc++.h>

using namespace std;
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define f_in freopen("test.in","r",stdin);
#define f_out freopen("test.in","w",stdout);
#define debug(x) cerr << #x << " : " << x << "\n";
#define _ cin.sync_with_stdio(0); cin.tie(0);
#define tl cout <<"\nTime elapsed: "<<(1000 * clock() / CLOCKS_PER_SEC)<<"ms\n"


typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vl;

inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

template<typename T = int>
inline T nxt(){
    char c=nc();T x=0; int f=1;
    for(;c>'9'||c<'0';c=nc())if(c=='-')f=-1;
    for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc()); x*=f;
    return x;
}

const int N = 100010;
int x[N];

struct node{
    int L, R, D;
    node(){};
    node(int l, int r, int d): L(l), R(r), D(d) {};
};
vector<node> v;

int main(){
    int n = nxt(), m = nxt();
    rep(i,0,m){
        int l = nxt(), r = nxt(), d = nxt();
        if(l > r) d = -d. swap(l, r);
        v.emplace_back(l, r, d);
    }
    sort(all(v), [&](const node& x, const node& y){
                        if(x.L != y.L) return x.L < y.L;
                        return x.R < y.R;
                        });
    memset(x, -1, sizeof x);
    rep(i,0,m){
        if(x[v[i].L] == -1 && x[v[i].R] == -1) x[v[i].L] = 0, x[v[i].R] = v[i].D;
        if(x[v[i].L] != -1 && x[v[i].R] == -1) x[v[i].R] = x[v[i].L] + v[i].D;
        if(x[v[i].L] != -1 && x[v[i].R] != -1){
            if(x[v[i].R] - x[v[i].L] != v[i].D){
                cout << "NO\n";
                return 0;
            }
        }
    }
    cout << "YES\n";
}
