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 (Clang 3.8.0) (judge verdict: Accepted)



#if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>
#include <list>

auto& in = std::cin;
auto& out = std::cout;
#define all_range(C) std::begin(C), std::end(C)
const double PI = 3.141592653589793238462643383279502884197169399375105820974944;


template<typename T, typename U>
std::enable_if_t<std::rank<T>::value == 0> fill_all(T& arr, const U& v) {
	arr = v;
}
template<typename ARR, typename U>
std::enable_if_t<std::rank<ARR>::value != 0> fill_all(ARR& arr, const U& v) {
	for (auto& i : arr) {
		fill_all(i, v);
	}
}

std::vector<std::pair<int, int>> graph[100000];

int32_t circuit_begin = -1;
std::vector<std::pair<int, int>> circuit;
int32_t color[100000];
//奇数長閉路検出の二彩色
bool func(int i, int c)
{

	if (color[i] == c) {
		return false;
	}
	if (color[i] == -c) {
		circuit_begin = i;
		return true;
	}

	color[i] = c;

	for (auto& next : graph[i]) {
		if (func(next.first, -c)) {
			if (circuit_begin != -1) {
				circuit.push_back(next);
				if (circuit_begin == i) {
					circuit_begin = -1;
				}
			}
			return true;
		}
	}
	return false;
}

int64_t V[100000];
bool func2(int i, int32_t p, int32_t s)
{
	auto tmpv = s - V[p];
	if (tmpv < 0) {
		return false;
	}
	if (V[i] != -1) {
		return V[i]==tmpv;
	}

	V[i] = tmpv;

	for (auto& next : graph[i]) {
		if (next.first == p) { continue; }
		if (!func2(next.first, i, next.second)) {
			return false;
		}
	}
	return true;
}
bool func2_2(int i, int32_t p, int32_t s)
{
	auto tmpv = s - V[p];
	//if (tmpv < 0) {
	//	return false;
	//}
	if (V[i] != -1) {
		return V[i] == tmpv;
	}

	V[i] = tmpv;

	for (auto& next : graph[i]) {
		if (next.first == p) { continue; }
		if (!func2_2(next.first, i, next.second)) {
			return false;
		}
	}
	return true;
}
bool ng_flag = false;
bool used[100000];
int64_t func3(int i, int32_t p, int32_t s, bool ismax)
{
	used[i] = true;
	if (ismax) {
		int64_t max_v = s;
		for (auto& next : graph[i]) {
			if (next.first == p) { continue; }
			if (used[next.first]) { continue; }
			max_v = std::min(max_v, next.second - func3(next.first, i, next.second, !ismax));
		}
		if (max_v < 1) {
			ng_flag = true;
		}
		return max_v;
	}
	else {
		int64_t min_v = 1;
		for (auto& next : graph[i]) {
			if (next.first == p) { continue; }
			if (used[next.first]) { continue; }
			min_v = std::max(min_v, next.second - func3(next.first, i, next.second, !ismax));
		}
		if (min_v > 1000000000) {
			ng_flag = true;
		}
		return min_v;
	}
}

int32_t N,M;
int main()
{
	using std::endl;
	in.sync_with_stdio(false);
	out.sync_with_stdio(false);
	in.tie(nullptr);
	out.tie(nullptr);

	in >> N>>M;
	for (int32_t i = 0; i < M; i++)
	{
		int a, b,c;
		in >> a >> b>>c; --a; --b;

		graph[a].emplace_back(b, c);
		graph[b].emplace_back(a, c);
	}

	if (func(0, 1)) {

		int64_t now_v = 0;
		for (size_t i = 0; i < circuit.size(); i++)
		{
			now_v = circuit[i].second - now_v;
		}

		if ((now_v < 0) || (now_v & 1)) {
			out << 0 << endl;
			return 0;
		}

		now_v /= 2;
		if (now_v > 1000000000) {
			out << 0 << endl;
			return 0;
		}
		fill_all(V, -1);
		V[circuit.front().first] = now_v;
		for (auto& next : graph[circuit.front().first]) {
			if (!func2(next.first, circuit.front().first, next.second)) {
				out << 0 << endl;
				return 0;
			}
		}
		out << 1 << endl;
		return 0;
	}
	else
	{
		fill_all(V, -1);
		V[0] = 0;
		//値が一致すれば遇閉路はOK
		for (auto& next : graph[0]) {
			if (!func2_2(next.first, 0, next.second)) {
				out << 0 << endl;
				return 0;
			}
		}

		fill_all(used, false);
		auto max = func3(0, -1, 1000000000, true);
		fill_all(used, false);
		auto min = func3(0, -1, 0, false);
		if (ng_flag) {
			out << 0 << endl;
			return 0;
		}
		else {
			out << (max - min + 1) << endl;
		}
	}

	return 0;
}
#endif