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

#include <queue>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <algorithm>

#include <cmath>

#include <iomanip>



using namespace std;



#define REP(i,n) for(ll (i) = (0); (i) < (n); ++i)

#define PB push_back

#define MP make_pair

#define FI first

#define SE second

#define ALL(v) v.begin(),v.end()

#define INF 1100000000

#define LLINF 1000000000000000000LL

#define MOD 1000000007

#define Decimal fixed << setpresicion(20)

#define SHOWP(x) cerr<<"("<<(x).FI<<", "<<(x).SE<<")"<<endl;

#define SHOWX(x) cerr<<#x<<": "<<x<<endl;

#define SHOWVEC(v, e) REP(i, e) cerr << (v[i]) << ' '; cerr << endl;

#define SHOW2D(a, h, w) REP(i, h){REP(j, w)cerr<<setw(3)<<(a[i][j])<<' ';cerr<<endl;}



typedef long long ll;

typedef pair<ll, ll> P;



vector<P> vv[110000];

ll v[110000];

bool used[110000];



bool dfs(int from, int x)

{

  if (used[from]) return v[from] == x;

  v[from] = x;

  used[from] = true;

  for (auto to : vv[from]) {

    if (!dfs(to.FI, x + to.SE)) return false;

  }

  return true;

}



int main()

{

  ll N, M;

  cin >> N >> M;

  REP(i, M) {

    ll L, R, D;

    cin >> L >> R >> D;

    L--; R--;

    vv[L].PB(MP(R, D));

    vv[R].PB(MP(L, -D));

  }



  bool flag = true;

  REP(i, N) {

    if (!used[i] && !dfs(i, 0)) flag = false;

  }

  if (flag) cout << "Yes" << endl;

  else cout << "No" << endl;



  return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.7840518245455463x):
#include <iostream>

#include <queue>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <algorithm>

#include <cmath>

#include <iomanip>



using namespace std;



#define REP(i,n) for(ll (i) = (0); (i) < (n); ++i)

#define PB push_back

#define MP make_pair

#define FI first

#define SE second

#define ALL(v) v.begin(),v.end()

#define INF 1100000000

#define LLINF 1000000000000000000LL

#define MOD 1000000007

#define Decimal fixed << setpresicion(20)

#define SHOWP(x) cerr<<"("<<(x).FI<<", "<<(x).SE<<")"<<endl;

#define SHOWX(x) cerr<<#x<<": "<<x<<endl;

#define SHOWVEC(v, e) REP(i, e) cerr << (v[i]) << ' '; cerr << endl;

#define SHOW2D(a, h, w) REP(i, h){REP(j, w)cerr<<setw(3)<<(a[i][j])<<' ';cerr<<endl;}



typedef long long ll;

typedef pair<ll, ll> P;



int par[110000];

int rnk[110000];

ll dw[110000];

void init(int n)

{

  REP(i, n) {

    par[i] = i;

    rnk[i] = 0;

  }

}

int find(int x)

{

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

  else {

    int p = find(par[x]);

    dw[x] += dw[par[x]];

    return par[x] = p;

  }

}

int weight(int x)

{

  find(x);

  return dw[x];

}

int diff(int x, int y)

{

  return weight(y) - weight(x);

}

void unite(int x, int y, int w)

{

  w += weight(x);

  w -= weight(y);



  x = find(x);

  y = find(y);

  if (x == y) return;



  if (rnk[x] < rnk[y]) swap(x, y), w = -w;

  if (rnk[x] == rnk[y]) rnk[x]++;

  par[y] = x;

  dw[y] = w;

}

bool same(int x, int y)

{

  return find(x) == find(y);

}



int main()

{

  ll N, M;

  cin >> N >> M;

  init(N);

  REP(i, M) {

    ll L, R, D;

    cin >> L >> R >> D;

    L--; R--;

    if (! same(L, R)) unite(L, R, D);

    else {

      if (diff(L, R) != D) {

        cout << "No" << endl;

        return 0;

      }

    }

  }

  cout << "Yes" << endl;



  return 0;

}