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;
    
    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 falsee=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][0]]=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[i2][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]==block[info[i1][1]]){
                    block[i2]=block[info[i1][0]];
                    x[i2]=x[i2]+i3;
                }
            }
            //printf("r4\n");
            
        }else if(block[info[i1][1]] < block[info[i2][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]){
                falsee=1;
            }
            //printf("r6\n");
            
        }
        if(falsee==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]]);
        
    }
    /*
    for(i1=0;i1<n;i1++){
        printf(" %d: x %d, block %d\n",i1,x[i1],block[i1]);
    }
    */
    //printf("%d",falsee);
    if(falsee==1){
        printf("no");
    }else{
        printf("yes");
    }
    
    return 0;
}