#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define vec2(a,b) vector<vec>(a,vec(b))
#define vec2ll(a,b) vector<vecll>(a,vecll(b))
#define vec3(a,b,c) vector<vector<vec>>(a,vec2(b,c))
#define vec3ll(a,b,c) vector<vector<vecll>>(a,vec2ll(b,c))
#define fi first
#define se second
#define endl "\n"
#define all(c) begin(c),end(c)
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),x))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),x))
#define MM " "
#define INF 100000000
using namespace std;
int in() {int x;cin>>x;return x;}
ll lin() {ll x;cin>>x;return x;}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}
template<class T> inline void print(pair<T,T> p){cout<<"("<<p.first<<","<<p.second<<") ";}
template<class T> inline void print(vector<pair<T,T>> v){for(auto e:v)print(e); cout<<endl;}
template<class T> inline void print(T v){for(auto e:v)cout<<e<<" ";cout<<endl;}


    
void go();

main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);cout<<fixed<<setprecision(15);
    int tc=1;
    // tc=in();
    while(tc--){
        go();
    }
    return 0;
}
template< typename T >
struct edge {
  int src, to;
  T cost;

  edge(int to, T cost) : src(-1), to(to), cost(cost) {}

  edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

  edge &operator=(const int &x) {
    to = x;
    return *this;
  }

  operator int() const { return to; }
};

template< typename T >
using Edges = vector< edge< T > >;
template< typename T >
using WeightedGraph = vector< Edges< T > >;
using UnWeightedGraph = vector< vector< int > >;
template< typename T >
using Matrix = vector< vector< T > >;
struct UnionFind {
  vector< int > data;
 
  UnionFind(int sz) {
    data.assign(sz, -1);
  }
 
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if(x == y) return (false);
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }
 
  int find(int k) {
    if(data[k] < 0) return (k);
    return (data[k] = find(data[k]));
  }
 
  int size(int k) {
    return (-data[find(k)]);
  }
};

bool det;
ll num;
vec d;
WeightedGraph<ll> g;
vecll mem;
int dfs(int x,int p,int c,ll s){
    d[x]=c;
    if(x!=0){
        mem[x]=s-mem[p];
    }
    for(auto e:g[x]){
        if(e!=p)dfs(e,x,c+1,e.cost);
    }
}

void go(){
    int n=in(),m=in();
    g.resize(n);
    d.resize(n);
    mem.resize(n);
    UnionFind uf(n);
    vector<edge<ll>> q;
    rep(i,m){
        int u=in()-1,v=in()-1;
        ll c=lin();
        if(uf.unite(u,v)){
            g[u].eb(v,c);
            g[v].eb(u,c);
        }
        else{
            q.eb(u,v,c);
        }
    }
    dfs(0,-1,0,0);
    bool flag=true;
    ll l=1 , r= LONG_LONG_MAX;
    for(auto e:q){
        int u = (d[e.src] & 1);
        int v = (d[e.to] & 1);
        if(u == v){
            ll tmp = e.cost - mem[e.src] - mem[e.to];
            ll T;
            if(tmp & 1) {
                cout<<0<<endl;
                return;
            }
            if(u) T = -tmp/2;
            else T = tmp/2;
            if(det) flag&= (num == T);
            else num = T,det = 1;
        }
        else{
            flag &= (e.cost == (mem[e.src] + mem[e.to]));
        }
    }
    rep(i,n){
        ll &now = mem[i];
        if(d[i]&1){
            chmin(r , now-1);
        }
        else chmax(l,1-now);
    }
    if(!flag or l>r){
        cout<<0<<endl;
    }
    else{
        cout<<(det ? 1 : r-l+1)<<endl;
    }
        
}


Measured memory_bytes: 12544