#include<bits/stdc++.h>
#define ALL(c) (c).begin(),(c).end()
#define EACH(i,c) for(auto i=(c).begin();i!=(c).end();++i)
using namespace std;
typedef long long ll;

typedef ll Weight;
struct Edge{
    int from, to;
    Weight weight;
    int rev;     // 無向グラフの対の辺
    Edge(int from, int to, Weight weight) :
        from(from), to(to), weight(weight) { }
    Edge(int from, int to, Weight weight, int rev) :
        from(from), to(to), weight(weight), rev(rev){ }
};
bool operator < (const Edge &a, const Edge &b){
    if(a.weight != b.weight) return a.weight > b.weight;
    if(a.from != b.from) return a.from > b.from;
    return  a.to > b.to;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void addFlowEdge(Graph &g, int a, int b, Weight c){
    g[a].push_back(Edge(a, b, c, g[b].size()));
    g[b].push_back(Edge(b, a, 0, g[a].size() - 1));
}
void addUndirectedEdge(Graph &g, int a, int b, Weight c){
    g[a].push_back(Edge(a, b, c, g[b].size()));
    g[b].push_back(Edge(b, a, c, g[a].size() - 1));
}

bool bipartiteDfs(const Graph &g, int v, int c, vector<int> &color) {
	int nc = c ^ 1;
	color[v] = c;
	for (auto e: g[v]) {
		if (color[e.to] >= 0) {
			if (color[e.to] != nc) {
				return false;
			}
		} else {
			bool res = bipartiteDfs(g, e.to, nc, color);
			if (!res) {
				return false;
			}
		}
	}

	return true;
}

pair<bool, vector<int>> isBipartite(const Graph &g) {
	int n = g.size();
	vector<int> color(n, -1);
	int c = 0;
	for(int v = 0; v < n; ++v) if(color[v] < 0) {
		bool t = bipartiteDfs(g, v, c, color);
		if (!t) return make_pair(false, color);
		c += 2;
	}
	return make_pair(true, color);
}

bool dfs1(Graph &g, int v, ll c, int col, vector<int> &vst, vector<ll> &d, vector<int> &color) {
	vst[v] = 1;
	d[v] = c;
	color[v] = col;
	int nc = col ^ 1;

	bool res = true;
	for(auto e: g[v]) {
		if(vst[e.to] == 0) {
			res &= dfs1(g, e.to, e.weight - c, nc, vst, d, color);
		} else if (nc != color[e.to]) {
			res = false;
		}
	}
	return res;
}

void fillval(Graph &g, int v, ll c, vector<int> &vst, vector<ll> &d) {
	vst[v] = 1;
	d[v] = c;
	for(auto e: g[v]) if (vst[e.to] == 0) {
		fillval(g, e.to, e.weight - c, vst, d);
	}
}

bool validate(Graph &g, vector<ll> &d) {
	for(auto a: d) {
		if(a <= 0) return false;
	}
	for(int i = 0; i < g.size(); ++i) {
		for(auto e: g[i]) {
			if(d[e.from] + d[e.to] != e.weight) {
				return false;
			}
		}
	}
	return true;
}

int main(){
	int n, m;
	cin >> n >> m;

	Graph g(n);
	for(int i = 0; i < m; ++i) {
		int u, v, s;
		cin >> u >> v >> s;
		addUndirectedEdge(g, u-1, v-1, s);
	}

	vector<int> color(n, -1);
	vector<ll> filled(n);
	vector<ll> d(n);
	vector<int> vst(n), vst2(n);

	bool bip = dfs1(g, 0, 0, 0, vst, d, color);
	if(bip) {
		ll mind = (ll)1e+16, maxd = 0;
		for(int i = 0; i < n; ++i) {
			if(color[i] == color[0]) {
				maxd = max(maxd, -d[i] + 1);
			} else {
				mind = min(mind, d[i] - 1);
			}
		}
		ll res = mind - maxd + 1;
		if(res < 0) res = 0;

		fillval(g, 0, maxd, vst2, filled);
		if(validate(g, filled)) {
			cout << res << endl;
		} else {
			cout << 0 << endl;
		}
	} else {
		bool flag = false;
		ll initc;
		for(int i = 0; i < n; ++i) {
			for(auto e: g[i]) {
				if(color[e.from] == color[e.to]) {
					initc = (e.weight - d[e.from] - d[e.to]) / 2;
					if(color[0] != color[e.from]) {
						initc = -initc;
					}
					flag = true;
					break;
				}
			}
			if(flag) break;
		}
		fillval(g, 0, initc, vst2, filled);
		if(validate(g, filled)) {
			cout << 1 << endl;
		} else {
			cout << 0 << endl;
		}
	}

	return 0;
}


Measured memory_bytes: 22912