#include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
/// {{{ DEBUG --- ///
#ifdef DEBUG
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#ifdef USE_COUT
#define dump(...) (cout<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#else
#define dump(...) (cerr<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<make_tuple(__VA_ARGS__)<<"\n")
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (0)
#endif
/// }}}--- ///


const int N = 1e5;
vector<pair<int, int>> g[N];
int n, m;

/// --- Graph Template {{{ ///

template<class T>
struct Edge {
  int from, to; T cost;
  Edge(int to, T cost) : from(-1), to(to), cost(cost) {}
  Edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
};
template<class T>
using WeightedGraph = vector< vector< Edge<T> > >;
using UnWeightedGraph = vector< vector<int> >;
inline void read(int &n, int &m, UnWeightedGraph &g) {
  cin >> n >> m;
  g.resize(n);
  for(int i = 0; i < m; i++) {
    int a, b; cin >> a >> b; a--; b--;
    g[a].emplace_back(b);
    g[b].emplace_back(a);
  }
}

/// }}}--- ///


UnWeightedGraph gr;

void dfs(int i, int p, vector<ll> &val, vector<int> &used, int &ended, int &nexi, ll &nexv, int step = 1) {
  used[i] = step;
  for(auto to : g[i]) {
    int j, cost;
    tie(j, cost) = to;
    if(used[j]) {
      if(j == p) continue;
      if(used[i] != used[j]) continue;
      dump(i, j, val[i], val[j]);
      ll t = val[i] + val[j];
      ll res = cost - t;
      nexi = j;
      nexv = val[j] + res / 2;
      ended = 1;
      return;
    }
    val[j] = cost - val[i];
    dfs(j, i, val, used, ended, nexi, nexv, 3 - step);
    if(ended) return;
  }
}
void dfs2(int i, vector<ll> &val, vector<int> &used) {
  if(used[i]) return;
  used[i] = 1;
  for(auto to : g[i]) {
    int j, cost;
    tie(j, cost) = to;
    if(used[j]) {
      continue;
    }
    val[j] = cost - val[i];
    dfs2(j, val, used);
  }
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0);
  cin >> n >> m;
  gr = UnWeightedGraph(n);
  for(int i = 0; i < m; i++) {
    int a, b, s; cin >> a >> b >> s;
    a--; b--;
    g[a].emplace_back(b, s);
    g[b].emplace_back(a, s);
    gr[a].emplace_back(b);
    gr[b].emplace_back(a);
  }
  // Biedge eca(gr);
  vector<int> col(n, 0);
  vector<int> used(n, 0);
  queue<int> q;
  q.emplace(0);
  col[0] = 1;
  int isNibu = 1;
  while(q.size()) {
    int i = q.front();
    q.pop();
    for(int j : gr[i]) {
      if(col[j] != 0) {
        if(col[j] == col[i]) {
          isNibu = 0;
          break;
        }
        continue;
      }
      if(col[j] == 0) {
        col[j] = 3-col[i];
        q.emplace(j);
      }
    }
    if(!isNibu) break;
  }
  if(isNibu) {
    dump("nibu!!");
    ll mi[2] = {(ll)1e18, (ll)1e18};
    vector<ll> val(n);
    vector<int> used(n);
    dfs2(0, val, used);
    dump(val);
    for(int i = 0; i < n; i++) {
      mi[col[i]-1] = min(mi[col[i]-1], val[i]);
    }
    dump(mi[0], mi[1]);
    mi[1] += mi[0] - 1;
    mi[0] = 1;
    ll ans = 0;
    if(mi[1] < 1) ans = 0;
    else ans = mi[1];
    for(int i = 0; i < n; i++) for(auto to : g[i])
      if(val[i] + val[to.first] != to.second) ans = 0;
    cout << ans << endl;
  } else {
    dump("not nibu!!");
    int nexi = 0;
    ll nexv = 0;
    {
      vector<ll> val(n);
      vector<int> used(n);
      int ended = 0;
      dfs(0, -1, val, used, ended, nexi, nexv);
    }
    int ans = 1;
    dump(nexi, nexv);
    {
      vector<ll> val(n);
      vector<int> used(n);
      val[nexi] = nexv;
      dfs2(nexi, val, used);
      for(int i = 0; i < n; i++) if(val[i] < 1) ans = 0;
      for(int i = 0; i < n; i++) for(auto to : g[i])
        if(val[i] + val[to.first] != to.second) ans = 0;
    }
    cout << ans << endl;
  }
  return 0;
}



Measured memory_bytes: 22048