#include <iostream>
#include <vector>
#include <limits.h>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <bitset>
#include <cassert>
#include <random>
#include <functional>
#include <stack>
#include <iomanip>
#include <cassert>
//#include <boost/multiprecision/cpp_int.hpp>
#include <complex>
#include <cstdio>
#include <list>
#include <bitset>

//< in.txt > out.txt
using namespace std;
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
const long long MOD = 998244353;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
typedef pair<LL, LL> PLL;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef unsigned long long ULL;
//typedef boost::multiprecision::cpp_int bigint;

template<class T>
struct Gedge {
	LL src, to;
	T cost;
	Gedge(LL s, LL t, T c) :src(s), to(t), cost(c) {}
	Gedge(LL t, T c) :src(-1), to(t), cost(c) {}
};

template<class T>
using WeightedGraph = vector<vector<Gedge<T>>>;
using UnweightedGraph = vector<vector<LL>>;
template<class T>
using Gedges = vector<Gedge<T>>;

struct TNode {
	LL parent;
	VLL childs;
	TNode() :parent(-1) {};
};
using Tree = vector<TNode>;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	LL N, M;
	cin >> N >> M;
	vector<Gedges<LL>> edges(N);
	Tree tree(N);
	vector<PLL> eq(N,PLL(0,0));
	for (LL m = 0; m < M; m++) {
		LL u, v, s;
		cin >> u >> v >> s;
		u--; v--;
		edges[u].push_back({ u,v,s });
		edges[v].push_back({ v,u,s });
	}
	//木の形に整理
	for (LL n = 0; n < N; n++)tree[n].parent = -2;
	queue<PLL> que;
	que.push(PLL(0,-1));
	while (!que.empty()) {
		LL cur = que.front().first;
		LL par = que.front().second;
		que.pop();
		if (tree[cur].parent != -2)continue;
		tree[cur].parent = par;
		if (par != -1) {
			tree[par].childs.push_back(cur);
		}
		for (auto e : edges[cur]) {
			if (e.to == par)continue;
			que.push(PLL(e.to,cur));
		}
	}
	//頂点0をxとして、各頂点の数を求める
	eq[0].first = 1;
	for (LL ch : tree[0].childs)que.push(PLL(ch, -1));
	que.push(PLL(0,-1));
	while (!que.empty()) {
		LL cur = que.front().first;
		que.pop();
		for (auto e : edges[cur]) {
			if (e.to != tree[cur].parent)continue;
			eq[cur] = PLL(-eq[tree[cur].parent].first, e.cost - eq[tree[cur].parent].second);
			break;
		}
		for (LL ch : tree[cur].childs)que.push(PLL(ch,-1));
	}
	//st <= x <= en
	LL st = 1, en = 1e18;
	for (LL n = 0; n < N; n++) {
		if (eq[n].first == 1) {
			st = max(1 - eq[n].second, st);
		}
		else {
			en = min(eq[n].second - 1, en);
		}
	}
	if (st > en) {
		cout << 0 << "\n";
		return 0;
	}
	for (LL n = 0; n < N; n++) {
		for (auto e : edges[n]) {
			if (e.to == tree[n].parent)continue;
			LL a = eq[n].first + eq[e.to].first;
			LL b = eq[n].second + eq[e.to].second;
			if (a == 0) {
				if (b != e.cost) {
					cout << 0 << "\n";
					return 0;
				}
			}
			else {
				if((e.cost-b)&1){
					cout << 0 << "\n";
					return 0;
				}
				else {
					LL x = (e.cost - b) / a;
					if(x < st || en < x || x <= 0) {
						cout << 0 << "\n";
						return 0;
					}
					st = x;
					en = x;
				}
			}
		}
	}
	cout << en - st + 1 << "\n";
	return 0;
}


Measured memory_bytes: 16640