#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<vector>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#define rep(index,num) for(int index=0;index<num;index++)
#define rep1(index,num) for(int index=1;index<=num;index++)
#define scan(argument) cin>>argument
#define prin(argument) cout<<argument<<endl
#define kaigyo cout<<endl
#define eps 1e-7
#define mp(a1,a2) make_pair(a1,a2)
#define ALL(a) (a).begin(),(a).end()
#define rALL(a) (a).rbegin(),(a).rend()
typedef long long ll;
typedef long double ld;
using namespace std;
typedef pair<ll,ll> pll;
typedef pair<int,int> pint;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<pint> vpint;
typedef vector<pll> vpll;
ll INFl=1e+18+1;
int INF=1e+9+1;
struct UnionFind{
  vector<int> par;
  vector<int> sizes;
  UnionFind(int n) : par(n), sizes(n, 1) {
    rep(i,n) par[i] = i;
  }
  int root(int x) {
    if (x == par[x]) return x;
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (sizes[x] < sizes[y]) swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
  }
  bool same(int x, int y) {
    return root(x) == root(y);
  }
  int size(int x) {
    return sizes[root(x)];
  }
};
vpll adj[100001];
int color[100001],d[100001];
ll cost[100001];
ll modmin[2]={INFl,INFl};
bool evencontra=0;
void dfs_visit_even(int u,ll c,int depth){
	color[u]=1;
	cost[u]=c;
	d[u]=depth;
	modmin[depth%2]=min(modmin[depth%2],c);
	rep(i,adj[u].size()){
		int v=adj[u][i].first;
		ll nextc=adj[u][i].second-c;
		if(color[v]==0){
			dfs_visit_even(v,nextc,depth+1);
		}
		else if(nextc!=cost[v]&&(d[u]-d[v])%2==1){
			evencontra=1;
		}
	}
}
bool oddcontra=0;
ll sa=INFl;
void dfs_visit_odd(int u,ll c,int depth){
	color[u]=1;
	cost[u]=c;
	d[u]=depth;
	modmin[depth%2]=min(modmin[depth%2],c);
	rep(i,adj[u].size()){
		int v=adj[u][i].first;
		ll nextc=adj[u][i].second-c;
		if(color[v]==0){
			dfs_visit_odd(v,nextc,depth+1);
		}
		else if((d[u]-d[v])%2){
			if(nextc!=cost[v]) oddcontra=1;
		}
		else{
			if(oddcontra==0){
				if(sa==INFl) sa=abs(nextc-cost[v]);
				else if(sa!=abs(nextc-cost[v])) oddcontra=1;
			}
		}
	}
}
int main(){
	int N,M;
	int a[100001],b[100001];
	ll s[100001];
	scan(N>>M);
	rep(i,M){
		scan(a[i]>>b[i]>>s[i]);
		a[i]--; b[i]--;
		adj[a[i]].push_back({b[i],s[i]});
		adj[b[i]].push_back({a[i],s[i]});
	}
	UnionFind uf(N*2);
	rep(i,M){
		uf.unite(a[i],b[i]+N);
		uf.unite(a[i]+N,b[i]);
	}
	bool bipartite = true;
	rep(i,N){
		if(uf.same(i,N+i)) bipartite = false;
	}
	if(bipartite){
		dfs_visit_even(0,1,0);
		//rep(i,N) printf("cost[%d]:%lld\n",i+1,cost[i]);
		//printf("evencontra:%d\n",evencontra);
		if(evencontra) prin(0);
		else{
			ll agemin=1-modmin[0],sagemax=modmin[1]-1;
			//printf("age:%lld sage:%lld\n",agemin,sagemax);
			prin(max(0LL,sagemax-agemin+1));
		}
	}
	else{
		dfs_visit_odd(0,1,0);
		//rep(i,N) printf("cost[%d]:%lld\n",i+1,cost[i]);
		//printf("oddcontra:%d\n",oddcontra);
		if(oddcontra) prin(0);
		else{
			ll agemin=1-modmin[0],sagemax=modmin[1]-1;
			//printf("sa:%lld age:%lld sage:%lld\n",sa,agemin,sagemax);
			if(sa==INFl||(sa%2==0&&agemin<=sa/2&&sa/2<=sagemax)) prin(1);
			else prin(0);
		}
	}
	return 0;
}


Measured memory_bytes: 18816