#include <bits/stdc++.h>

#define _overload(_1,_2,_3,name,...) name
#define _rep(i,n) _range(i,0,n)
#define _range(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)

#define _rrep(i,n) _rrange(i,n,0)
#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)
#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)

#define _all(arg) begin(arg),end(arg)
#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))
#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)
#define clr(a,b) memset((a),(b),sizeof(a))
#define bit(n) (1LL<<(n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}
template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}

using ll=long long;
using R=long double;
const R EPS=1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R& r){return(r > EPS)-(r < -EPS);}
inline R sq(R x){return sqrt(max(x,0.0L));}

const int dx[8]={1,0,-1,0,1,-1,-1,1};
const int dy[8]={0,1,0,-1,1,1,-1,-1};

// Problem Specific Parameter:
// Description: グラフの型定義
// Verifyed: Many Diffrent Problem

//Appropriately Changed
using edge = struct {int to;ll cost;};
using G = vector<vector<edge>>;

void add_edge(G &graph, int from, int to,ll cost) {
	graph[from].push_back({to,cost});
	graph[to].push_back({from,cost});
}



const int limit = 100010;
const ll inf = 1LL << 50;
ll val[limit],color[limit];

bool bi = true;

vector<int> trace;
int prv[limit];


void bi_dfs(const G &graph,int v){
	for(auto &e:graph[v]){
		if(color[e.to] == -inf){
			color[e.to] = color[v] ^ 1;
			prv[e.to] = v;
			bi_dfs(graph,e.to);
		}else{
			if(color[v] == color[e.to]){
			
				if(bi == true){
					int cur = v;
					while(cur != e.to){
						trace.push_back(cur);
						cur = prv[cur];
					}
					trace.push_back(e.to);
				}

				bi = false;
			}
		}
	}
}


void val_dfs(const G &graph,int v){
	for(auto &e:graph[v]){
		if(val[e.to] == -inf){
			val[e.to] = e.cost - val[v];
			val_dfs(graph,e.to);
		}
	}
}


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

	G graph(n);
	rep(i,n) val[i] = color[i] = -inf;

	rep(i,m){
		int u,v,s;
		cin >> u >> v >> s;
		u--,v--;
		add_edge(graph,u,v,s);
	}

	color[0] = 0;
	bi_dfs(graph,0);
	
	if(bi == true){
		val[0] = 1;
		val_dfs(graph,0);
		bool ok = true;

		rep(v,n){
			for(auto &e: graph[v]){
				if(val[v] + val[e.to] != e.cost){
					ok = false;
				}
			}
		}

		if(ok){
			ll pmin = inf, mmin = inf;
			rep(v,n){
				if(color[v] == 0)
					chmin(pmin,val[v]);
				else
					chmin(mmin,val[v]);
			}

			const ll from = 1 - pmin;
			const ll to = mmin - 1;
			cout << max<ll>(0,to - from + 1) << endl;
		}else{
			cout << 0 << endl;
		}

	}else{
		const int a = trace.front();
		const int b = trace.back();

		const int len = trace.size();
		
		val[a] = 0;
		rep(i,len-1){
			const int cur = trace[i];
			const int nxt = trace[i+1];
			for(auto &e:graph[cur]){
				if(e.to == nxt){
					val[nxt] = e.cost - val[cur];
				}
			}
		}
		
		const int sum = val[a] + val[b];
		int tar;
		for(auto &e:graph[a]) if(e.to == b) tar = e.cost;

		if((tar - sum) % 2 == 1){
			cout << 0 << endl;
			return 0;
		}

		const int num = (tar - sum) / 2;
		rep(i,n) val[i] = -inf;
		val[a] = num;
		val_dfs(graph,a);

		bool ok = true;

		rep(v,n){
			if(val[v] <= 0) ok = false;
			for(auto &e: graph[v]){
				if(val[v] + val[e.to] != e.cost){
					ok = false;
				}
			}
		}

		if(ok)
			cout << 1 << endl;
		else
			cout << 0 << endl;

	}
	
	return 0;
}

Measured memory_bytes: 17536