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 Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_imports)]
use std::io::*;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

pub trait InputValue {
    fn parse(s: &str) -> Self;
}

pub fn read<T: InputValue>() -> T {
    let mut buf = String::new();
    let _ = stdin().read_line(&mut buf);
    T::parse(&buf.trim())
}

pub fn readn<T: InputValue>(n: usize) -> Vec<T> {
    let mut vec = vec![];
    for _ in 0..n {
        vec.push(read());
    }
    vec
}

pub fn readnc<T: InputValue>() -> Vec<T> {
    let mut vec = vec![];
    let line: String = read();
    for token in line.split_whitespace() {
        vec.push(T::parse(token));
    }
    vec
}

macro_rules! parse_single_value {
    ($($t:ty),*) => {
        $(
            impl InputValue for $t {
                fn parse(s: &str) -> $t { s.parse().unwrap() }
            }
        )*
	}
}
parse_single_value!(i32, i64, f32, f64, usize, String);

macro_rules! parse_tuple {
	($($t:ident),*) => {
		impl<$($t),*> InputValue for ($($t),*) where $($t: InputValue),* {
			fn parse(s: &str) -> ($($t),*) {
				let mut tokens = s.split_whitespace();
				let t = ($($t::parse(tokens.next().unwrap())),*);
				t
			}
		}
	}
}
parse_tuple!(A, B);
parse_tuple!(A, B, C);

// ===

struct Graph {
    vertices: Vec<Vertex>
}

impl Graph {
    fn new(n: usize) -> Self {
        Graph { vertices: vec![Vertex::new(); n] }
    }

    fn add_edge(&mut self, u: usize, v: usize, value: i32) {
        self.vertices[u].edges.push(Edge { to: v, value: value })
    }

    fn find_nonzero_loop(&self) -> bool {
        let n = self.vertices.len();
        let mut values = vec![0; n];
        let mut visited = vec![false; n];
        for i in 0..n {
            if !visited[i] {
                if !self.dfs(i, 0, &mut visited, &mut values) {
                    return true;
                }
            }
        }
        false
    }

    fn dfs(&self, idx: usize, dist: i32, visited: &mut Vec<bool>, values: &mut Vec<i32>) -> bool {
        if visited[idx] {
            return values[idx] == dist;
        }
        visited[idx] = true;
        values[idx] = dist;

        let mut res = true;
        for e in &self.vertices[idx].edges {
            res &= self.dfs(e.to, dist + e.value, visited, values);
        }
        res
    }
}

#[derive(Clone)]
struct Vertex {
    edges: Vec<Edge>
}

impl Vertex {
    fn new() -> Self {
        Vertex { edges: vec![] }
    }
}

#[derive(Clone)]
struct Edge {
    to: usize,
    value: i32
}


fn main() {
    let (n, m): (usize, usize) = read();
    let mut graph = Graph::new(n);
    for i in 0..m {
        let (u, v, d): (usize, usize, i32) = read();
        graph.add_edge(u-1, v-1, d);
        graph.add_edge(v-1, u-1, -d);
    }

    if graph.find_nonzero_loop() {
        println!("No");
    } else {
        println!("Yes");
    }
}