Problem:
Score : 400 points

Problem Statement

There are N people standing on the x-axis.
Let the coordinate of Person i be x_i.
For every i, x_i is an integer between 0 and 10^9 (inclusive).
It is possible that more than one person is standing at the same coordinate.

You will given M pieces of information regarding the positions of these people.
The i-th piece of information has the form (L_i, R_i, D_i).
This means that Person R_i is to the right of Person L_i by D_i units of distance, that is, x_{R_i} - x_{L_i} = D_i holds.

It turns out that some of these M pieces of information may be incorrect.
Determine if there exists a set of values (x_1, x_2, ..., x_N) that is consistent with the given pieces of information.

Constraints

1 \leq N \leq 100 000

0 \leq M \leq 200 000

1 \leq L_i, R_i \leq N (1 \leq i \leq M)

0 \leq D_i \leq 10 000 (1 \leq i \leq M)

L_i \neq R_i (1 \leq i \leq M)

If i \neq j, then (L_i, R_i) \neq (L_j, R_j) and (L_i, R_i) \neq (R_j, L_j).

D_i are integers.

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1 D_1
L_2 R_2 D_2
:
L_M R_M D_M

Output

If there exists a set of values (x_1, x_2, ..., x_N) that is consistent with all given pieces of information, print Yes; if it does not exist, print No.

Sample Input 1

3 3
1 2 1
2 3 1
1 3 2

Sample Output 1

Yes

Some possible sets of values (x_1, x_2, x_3) are (0, 1, 2) and (101, 102, 103).

Sample Input 2

3 3
1 2 1
2 3 1
1 3 5

Sample Output 2

No

If the first two pieces of information are correct, x_3 - x_1 = 2 holds, which is contradictory to the last piece of information.

Sample Input 3

4 3
2 1 1
2 3 5
3 4 2

Sample Output 3

Yes

Sample Input 4

10 3
8 7 100
7 9 100
9 8 100

Sample Output 4

No

Sample Input 5

100 0

Sample Output 5

Yes

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#define REP(i,n) for(int i=0;i<(n);++i)
#define ALL(v)   (v).begin(),(v).end()
#define debug(x) cerr<<#x<<": "<<(x)<<endl
#define INF      (int)1e9
#define EPS      (double)1e-9
#define MOD      ((int)1e9+7)
using namespace std;
typedef long long     llong;
typedef vector<int>   vi;
typedef vector<vi >   vvi;
typedef vector<vvi >  vvvi;
typedef pair<int,int> pii;
template<class Type> void line(const Type &a){int cnt=0;for(const auto &elem:a){if(cnt++)cerr<<' ';cerr<<elem;}cerr<<endl;}

inline void YESNO(bool ans){cout<<(ans?"YES":"NO")<<endl;}
inline void YesNo(bool ans){cout<<(ans?"Yes":"No")<<endl;}
inline void yesno(bool ans){cout<<(ans?"yes":"no")<<endl;}

/*重み付きUnionFind*/
template<typename Type>
struct PotentializedUnionFind{
	vi par;			//par[i]:=(0以上の場合iの親. 0未満の場合はiを含むグループのサイズ).
	vector<Type> w;	//w[i]:=(iがもつポテンシャル).
	int num;		//num:=(グループの数).
	
	PotentializedUnionFind(int n):par(n,-1),w(n,0){}//constructor.
	
	void init(){fill(ALL(par),-1), fill(ALL(w),0), num=par.size();}
	int root(int x){
		if(par[x]<0) return x;
		else{
			int r=root(par[x]);
			w[x]+=w[par[x]];
			return par[x]=r;
		}
	}
	int size(int x){return -par[root(x)];}
	Type weight(int x){
		root(x);
		return w[x];
	}
	bool same(int x,int y){return root(x)==root(y);}
	Type diff(int x,int y){return weight(y)-weight(x);}//xからみたyのポテンシャルの高さ. O(log N).
	bool unite(int x,int y,Type d){
		d=d+weight(x)-weight(y);
		x=root(x), y=root(y);
		if(x==y) return false;
		if(size(x)<size(y)) swap(x,y), d=-d;//merge tec(x<-y).
		par[x]+=par[y];
		par[y]=x;
		w[y]=d;
		num--;
		return true;
	}
};

//解説参考.
int main(){
	int n,m;
	cin>>n>>m;
	
	PotentializedUnionFind<llong> uf(n);
	bool ans=true;
	REP(i,m){
		int l,r,d;
		cin>>l>>r>>d;
		l--, r--;
		if(uf.same(l,r)){
			if(uf.diff(l,r)==d){}
			else{
				ans=false;
				break;
			}
		}else uf.unite(l,r,d);
	}
	
	YesNo(ans);
}