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 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int mini(int a, int b){
    if(a>b)return b; else return a;
}

int main(void)
{
    char str[1000];
    char *tok;
    
    int n,m;
    int info[200000][3];
    int blockcount=1;
    int block[100000];
    int x[100000];
    int i1,i2,i3,i4,i5;
    
    fgets(str, sizeof(str), stdin);
    tok=strtok(str," ");
    n=strtol(tok,NULL,10);
    tok=strtok(NULL," ");
    m=strtol(tok,NULL,10);
    //printf("%d\n",n);

    for(i1=0;i1<m;i1++){
        fgets(str, sizeof(str), stdin);
        tok=strtok(str," ");
        info[i1][0]=strtol(tok,NULL,10)-1;
        tok=strtok(NULL," ");
        info[i1][1]=strtol(tok,NULL,10)-1;
        tok=strtok(NULL," ");
        info[i1][2]=strtol(tok,NULL,10);
    }
    
    for(i1=0;i1<n;i1++){
        block[i1]=0;
    }
    
    blockcount=1;
    
    
    //printf("%d,%d,%d\n",info[0][0],info[0][1],info[0][2]);
    block[info[0][0]]=1;
    block[info[0][1]]=1;
    x[info[0][0]]=0;
    x[info[0][1]]=info[0][2];
    
    blockcount++;
    int false=0;
    
    for(i1=1;i1<m;i1++){
        //printf("%d,%d,%d\n",info[i1][0],info[i1][1],info[i1][2]);
        //printf("x[%d]:%d:b-%d,x[%d]:%d:b-%d\n",info[i1][0],x[info[i1][0]],block[info[i1][0]],info[i1][1],x[info[i1][1]],block[info[i1][1]]);
        
        if(block[info[i1][0]] + block[info[i1][1]]==0){
            block[info[i1][0]]=blockcount;
            block[info[i1][1]]=blockcount;
            blockcount++;
            x[info[i1][0]]=0;
            x[info[i1][1]]=info[i1][2];
            //printf("r1\n");
            
        }else if(block[info[i1][0]]==0){
            block[info[i1][0]]=block[info[i1][1]];
            x[info[i1][0]]=x[info[i1][1]]-info[i1][2];
            //printf("r2\n");
            
        }else if(block[info[i1][1]]==0){
            block[info[i1][1]]=block[info[i1][0]];
            x[info[i1][1]]=x[info[i1][0]]+info[i1][2];
            //printf("r3\n");
            
        }else if(block[info[i1][0]] < block[info[i1][1]]){
            i4=block[info[i1][1]];
            block[info[i1][1]]=block[info[i1][0]];
            i3=x[info[i1][0]]+info[i1][2]-x[info[i1][1]]; //ブロック間の座標の差分
            x[info[i1][1]]+=i3;
            for(i2=0;i2<n;i2++){
                if(block[i2]==i4){
                    block[i2]=block[info[i1][0]];
                    x[i2]=x[i2]+i3;
                }
            }
            //printf("r4\n");
            
        }else if(block[info[i1][1]] < block[info[i1][0]]){
            i4=block[info[i1][0]];
            block[info[i1][0]]=block[info[i1][1]];
            i3=x[info[i1][1]]+info[i1][2]-x[info[i1][0]]; //ブロック間の座標の差分
            x[info[i1][0]]+=i3;
            for(i2=0;i2<n;i2++){
                if(block[i2]==block[info[i1][0]]){
                    block[i2]=block[info[i1][1]];
                    x[i2]=x[i2]+i3;
                }
            }
            //printf("r5\n");
            
        }else{
            if(x[info[i1][1]]-x[info[i1][0]]!=info[i1][2]){
                false=1;
            }
            //printf("r6\n");
            
        }
        if(false==1){
            i1=m;
        }
        
        //printf("x[%d]:%d:b-%d,x[%d]:%d:b-%d\n",info[i1][0],x[info[i1][0]],block[info[i1][0]],info[i1][1],x[info[i1][1]],block[info[i1][0]]);
        
    }
    
    int b[100005];
    int c[100005];
    
    i3=0;
    for(i1=0;i1<n;i1++){
        i4=0;
        for(i2=0;i2<i3;i2++){
            if(block[i1]==b[i2])i4++;
        }
        if(i4==0){
            b[i3]=block[i1];
            i3++;
        }
    }
    
    
    for(i1=0;i1<i3;i1++){ //各連結部分について
        i4=0;
        for(i2=0;i2<n;i2++){
            if(b[i1]==block[i2]){
                c[i4]=i2;
                i4++;
            }
        }
        for(i2=0;i2<i4;i2++){ //人数分
            for(i5=0;i5<i2;i5++){
                if(x[c[i2]]==x[c[i5]])false=1;
            }
        }
    }
    
    
    /*
    for(i1=0;i1<n;i1++){
        printf(" %d: x %d, block %d\n",i1,x[i1],block[i1]);
    }*/
    
    //printf("%d",false);
    if(false==1){
        printf("No");
    }else{
        printf("Yes");
    }
    
    return 0;
}