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 C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include<bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define INF 1000000000
#define mod 1000000007
using ll=long long;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

// 木じゃないならたかだか1個

struct edge{
    int to;ll s;
    edge(int to,ll s):to(to),s(s){}
    edge(){}
};

signed main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n,m;cin>>n>>m;
    vector<vector<edge>> g(n);
    rep(i,m){
        int u,v;ll s;cin>>u>>v>>s;u--,v--;
        g[u].push_back(edge(v,s));
        g[v].push_back(edge(u,s));
    }

    vector<ll> con(n,0);// 定数項
    vector<bool> pos(n);// rの符号が正か

    vector<bool> check(n,false);
    ll r=-1;
    function<void(int,int)> dfs=[&](int pre,int now){
        // cout<<pre<<" -> "<<now<<endl;
        for(auto &e:g[now]){
            if(e.to==pre) continue;
            if(check[e.to]){
                // 成立するかチェック
                // 式now + 式to = e.sが成立すればrをチェック
                if(pos[now]!=pos[e.to]){
                    if(con[now]+con[e.to]!=e.s){
                        cout<<0<<endl;
                        exit(0);
                    }
                }else{
                    // 2*(±r) + con[now]+con[e.to]=e.s
                    ll tmp=e.s-con[now]-con[e.to];
                    if(tmp%2!=0){
                        cout<<0<<endl;
                        exit(0);
                    }
                    ll rtmp=tmp/2;
                    if(!pos[now]) rtmp=-rtmp;
                    if(rtmp<=0){
                        cout<<0<<endl;
                        exit(0);
                    }
                    // 既存のrと一致するか
                    if(r<0){
                        r=rtmp;
                    }else{
                        if(r!=rtmp){
                            cout<<0<<endl;
                            exit(0);
                        }
                    }
                }
            }else{
                // go
                ll c=e.s-con[now];
                con[e.to]=c;
                pos[e.to]=(1^pos[now]);
                check[e.to]=true;
                dfs(now,e.to);
            }
        }
    };

    con[0]=0;
    pos[0]=true;
    check[0]=true;
    dfs(-1,0);

    // debug(pos);
    // debug(con);
    

    if(r<0){
        // 未決定なら範囲を調べる
        ll lw=1,hi=LINF;
        rep(i,n){
            if(pos[i]){
                // lw
                // r+con[i]>=1
                chmax(lw,1-con[i]);
            }else{
                // hi
                // -r+con[i]>=1
                chmin(hi,con[i]-1);
            }
        }
        cout<<max(0ll,hi-lw+1)<<endl;
    }else{
        //決定済みならそれ1個のみ
        assert(false);
        cout<<1<<endl;
    }
    return 0;
}