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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Competitive
{
    internal class Solution
    {
        public int N, M;
        public Graph G;
        public void Run()
        {
            // Input
            {
                var line = Input.ReadIntArray();
                N = line[0];
                M = line[1];
            }
            G = new Graph(N);

            for (int i = 0; i < M; i++)
            {
                var line = Input.ReadIntArray();
                int u = line[0] - 1;
                int v = line[1] - 1;
                int s = line[2];
                var e1 = new Edge(u, v, s);
                var e2 = new Edge(v, u, s);
                e1.Reverse = e2;
                e2.Reverse = e1;
                G[u].Edges.Add(e1);
                G[v].Edges.Add(e2);
            }

            // Create Tree
            {
                var pq = new Queue<EdgeData>();
                pq.Enqueue(new EdgeData(1, new Edge(-1, 0, 1)));

                while (pq.Count() > 0)
                {
                    var d = pq.Dequeue();
                    var n = G[d.Edge.To];
                    if (n.Sign != 0) continue;

                    int from = d.Edge.From;
                    long fromValue = from == -1 ? 0 : G[from].Value;
                    n.Sign = d.Sign;
                    n.Value = d.Edge.Value - fromValue;
                    d.Edge.IsBranch = true;
                    if(d.Edge.Reverse != null)
                        d.Edge.Reverse.IsBranch = true;
                    foreach (var ee in n.Edges)
                    {
                        pq.Enqueue(new EdgeData(d.Sign * (-1), ee));
                    }
                }
            }

            // Branchでないもの
            List<Edge> consDiffSign = new List<Edge>();
            List<Edge> consSameSign = new List<Edge>();
            for (int i = 0; i < N; i++)
            {
                foreach (var e in G[i].Edges)
                    if(!e.IsBranch)
                    {
                        var from = G[e.From];
                        var to = G[e.To];
                        if (from.Sign == to.Sign) consSameSign.Add(e);
                        else consDiffSign.Add(e);
                    }
            }

            if (consDiffSign.Count != 0)
            {
                for (int c = 0; c < consDiffSign.Count; c++)
                {
                    var con = consDiffSign[c];
                    var from = G[con.From];
                    var to = G[con.To];
                    if (from.Value + to.Value != con.Value)
                    {
                        Console.WriteLine(0);
                        return;
                    }
                }
            }

            if (consSameSign.Count == 0)
            {
                // 制約が無い場合
                long plusMin = long.MaxValue;
                long minusMin = long.MaxValue;

                for (int i = 0; i < N; i++)
                {
                    if (G[i].Sign == 1) plusMin = Math.Min(plusMin, G[i].Value);
                    if (G[i].Sign == -1) minusMin = Math.Min(minusMin, G[i].Value);
                }

                long mn = 2 - Math.Min(plusMin, 1); // プラスノードに０以下がある場合、その分だけ足す必要がある
                long mx = minusMin; // マイナスノードが２なら、最大でも２まで

                Console.WriteLine(Math.Max(mx - mn + 1, 0));
            }
            else
            {
                long up;
                {
                    var con = consSameSign.First();
                    var fr = G[con.From];
                    var to = G[con.To];
                    var diff = (con.Value - (fr.Value + to.Value)) * fr.Sign;
                    if (diff < 0 || diff % 2 != 0)
                    {
                        Console.WriteLine(0);
                        return;
                    }

                    up = diff / 2;
                }

                for (int i = 0; i < N; i++)
                {
                    if (G[i].Value + up * G[i].Sign <= 0)
                    {
                        Console.WriteLine(0);
                        return;
                    }
                }

                for (int c = 0; c < consSameSign.Count; c++)
                {
                    var con = consSameSign[c];
                    var from = G[con.From];
                    var to = G[con.To];
                    if (from.Value + up * from.Sign + to.Value + up * to.Sign != con.Value)
                    {
                        Console.WriteLine(0);
                        return;
                    }
                }

                // Survived
                Console.WriteLine(1);
            }

        }
    }

    // libs ----------
    // 通常はIComparableのみが必要
    class EdgeData : IComparable<EdgeData>, IComparable
    {
        public int Sign;
        public Edge Edge;
        public EdgeData(int sign, Edge edge)
        {
            Sign = sign;
            Edge = edge;
        }

        public int CompareTo(EdgeData other)
        {
            return Sign.CompareTo(other.Sign);
        }

        public int CompareTo(object obj)
        {
            if (obj == null) return 1;
            if (GetType() != obj.GetType()) throw new ArgumentException();
            return CompareTo((EdgeData)obj);
        }
    }

    internal class Graph
    {
        public List<Node> Nodes;

        public Node this[int i]
        {
            set { Nodes[i] = value; }
            get { return Nodes[i]; }
        }

        public Graph(int N)
        {
            Nodes = new List<Node>();
            for (int i = 0; i < N; i++)
            {
                Nodes.Add(new Node(i));
            }
        }

    }

    internal class Node
    {
        public List<Edge> Edges;
        public int No;
        public int Sign;
        public long Value;

        public Node(int no)
        {
            this.No = no;
            Value = -1;
            Edges = new List<Edge>();
            Sign = 0;
        }
    }

    internal class Edge
    {
        public int From;
        public int To;

        public bool IsBranch;
        public long Value;
        public Edge Reverse;

        public Edge(int fr, int to, long value)
        {
            From = fr;
            To = to;
            Value = value;
            IsBranch = false;
        }

    }


    // common ----------

    internal static class Input
    {
        public static string ReadString()
        {
            string line = Console.ReadLine();
            return line;
        }

        public static int ReadInt()
        {
            string line = Console.ReadLine();
            return int.Parse(line);
        }

        public static int[] ReadIntArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(int.Parse).ToArray();            
        }

        public static long ReadLong()
        {
            string line = Console.ReadLine();
            return long.Parse(line);
        }

        public static long[] ReadLongArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            string line = Console.ReadLine();
            return line.Split(' ').Select(double.Parse).ToArray();
        }
    }
    
    internal class Program
    {
        public static void Main(string[] args)
        {
            var s = new Solution();
            s.Run();
        }
    }
}