Problem:
Score : 600 points

Problem Statement

Kenkoooo found a simple connected graph.
The vertices are numbered 1 through n.
The i-th edge connects Vertex u_i and v_i, and has a fixed integer s_i.

Kenkoooo is trying to write a positive integer in each vertex so that the following condition is satisfied:

For every edge i, the sum of the positive integers written in Vertex u_i and v_i is equal to s_i.

Find the number of such ways to write positive integers in the vertices.

Constraints

2 \leq n \leq 10^5

1 \leq m \leq 10^5

1 \leq u_i < v_i \leq n

2 \leq s_i \leq 10^9

If i\neq j, then u_i \neq u_j or v_i \neq v_j.

The graph is connected.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

n m
u_1 v_1 s_1
:
u_m v_m s_m

Output

Print the number of ways to write positive integers in the vertices so that the condition is satisfied.

Sample Input 1

3 3
1 2 3
2 3 5
1 3 4

Sample Output 1

1

The condition will be satisfied if we write 1,2 and 3 in vertices 1,2 and 3, respectively.
There is no other way to satisfy the condition, so the answer is 1.

Sample Input 2

4 3
1 2 6
2 3 7
3 4 5

Sample Output 2

3

Let a,b,c and d be the numbers to write in vertices 1,2,3 and 4, respectively.
There are three quadruples (a,b,c,d) that satisfy the condition:

(a,b,c,d)=(1,5,2,3)

(a,b,c,d)=(2,4,3,2)

(a,b,c,d)=(3,3,4,1)

Sample Input 3

8 7
1 2 1000000000
2 3 2
3 4 1000000000
4 5 2
5 6 1000000000
6 7 2
7 8 1000000000

Sample Output 3

0

Solution in Rust (1.15.1) (judge verdict: Accepted)

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::Read;
#[allow(dead_code)]
fn getline() -> String {
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok().unwrap();
    ret
}
fn get_word() -> String {
    let mut stdin = std::io::stdin();
    let mut u8b: [u8; 1] = [0];
    loop {
        let mut buf: Vec<u8> = Vec::with_capacity(16);
        loop {
            let res = stdin.read(&mut u8b);
            if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
                break;
            } else {
                buf.push(u8b[0]);
            }
        }
        if buf.len() >= 1 {
            let ret = String::from_utf8(buf).unwrap();
            return ret;
        }
    }
}

#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }

fn dfs(v: usize, a: i64, b: i64, g: &[Vec<(usize, i64)>],
       vis: &mut [bool], coef: &mut [(i64, i64)],
       cand: &mut Vec<i64>) -> bool {
    if vis[v] {
        if coef[v].0 == a {
            return coef[v].1 == b;
        }
        if (coef[v].1 - b) % (coef[v].0 - a) != 0 {
            return false;
        }
        cand.push(-(coef[v].1 - b) / (coef[v].0 - a));
        return true;
    }
    vis[v] = true;
    coef[v] = (a, b);
    for &(w, s) in g[v].iter() {
        if !dfs(w, -a, s - b, g, vis, coef, cand) {
            return false;
        }
    }
    return true;
}

const INF: i64 = 1 << 61;

fn solve() {
    let n = get();
    let m = get();
    let mut g = vec![Vec::new(); n];
    for _ in 0 .. m {
        let u = get::<usize>() - 1;
        let v = get::<usize>() - 1;
        let s: i64 = get();
        g[u].push((v, s));
        g[v].push((u, s));
    }
    let mut vis = vec![false; n];
    let mut coef = vec![(0, 0); n];
    let mut cand = Vec::new();
    if !dfs(0, 1, 0, &g, &mut vis, &mut coef, &mut cand) {
        println!("0");
        return;
    }
    cand.sort();
    cand.dedup();
    //println!("cand = {:?}", cand);
    if cand.len() >= 2 {
        println!("0");
        return;
    }
    let mut lo = 1; let mut hi = INF;
    for i in 0 .. n {
        if coef[i].0 == 1 {
            lo = max(lo, -coef[i].1 + 1);
        } else {
            hi = min(hi, coef[i].1 - 1);
        }
    }
    if cand.len() == 1 {
        let x = cand[0];
        println!("{}", if lo <= x && x <= hi { 1 } else { 0 });
        return;
    }
    println!("{}", if lo <= hi { hi - lo + 1 } else { 0 });
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}