#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


Measured memory_bytes: 11648