#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

#include <cmath>
#include <cstdlib>
#include <climits>

//#include <stdio.h>
//#include <stdlib.h>
//#include "show_vector.hh"

struct node{
  int L;
  int R;
  int D;
  node* Next = NULL;
};

using namespace std;

#define debug false

void show_node(node *n){
  printf("(L, R, D) = (%d, %d, %d)\n", n->L, n->R, n->D);
  return;
}
int main(int argc, char *argv[]){

  int N, M;
  cin >> N >> M;

  int x[N];
  for(int i = 0; i < N; i++){
    x[i] = INT_MIN;
  }
  int L, R, D;
  node *top[N], *tmp, *curr;
  int num_of_top[N] = {};
  for(int i = 0; i < N; i++)
    top[i] = NULL;
  for(int i = 0; i < M; i++){
    cin >> L >> R >> D;
    L--; R--;

    tmp = new node;
    tmp->L = L;
    tmp->R = R;
    tmp->D = D;
    tmp->Next = top[L];
    top[L] = tmp;
    num_of_top[L]++;

    int t = L;
    L = R; R = t;
    tmp = new node;
    tmp->L = L;
    tmp->R = R;
    tmp->D = -1*D;
    tmp->Next = top[L];
    top[L] = tmp;
    num_of_top[L]++;
  }

  vector<int> waiting, reachable;
  for(int i = 0; i < N; i++){
    waiting.push_back(i);
  }
  vector<int>::iterator itr;
  while(waiting.size() + reachable.size() > 0){
    //printf("where segfo2?\n");
    if(reachable.size() == 0){
      // waiting から一つ reachable に移動
      int node_w = waiting[0];
      x[node_w] = 0;
      waiting.erase(waiting.begin());
      reachable.push_back(node_w);
    }

    // reachable のものを全て処理
    int node_r = reachable[0];
    curr = top[node_r];
    while(curr != NULL){
      //show_node(curr);
      // L, R, D の設定
      L = curr->L;
      R = curr->R;
      D = curr->D;

      if(x[R] == INT_MIN){
        // 座標の設定
        x[R] = x[L] + D;
      }else{
        if(x[R] != x[L] + D) goto BADEND;
      }
      // Node の移動
      itr = find(waiting.begin(), waiting.end(), R);
      if(itr != waiting.end()){
        waiting.erase(itr);
        reachable.push_back(R);
      }

      // Node の整理
      tmp = curr;
      top[node_r] = curr->Next;
      curr = curr->Next;
      delete tmp;
    }
    reachable.erase(reachable.begin());

    //show_vector("waiting   : ", waiting);
    //show_vector("reachable : ", reachable);
  }
  printf("Yes\n");
  return 0;

  BADEND:
    printf("No\n");
  return 0;
}
