#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <cassert>

using namespace std;
typedef long long LL;
template <typename F, typename S> std::ostream& operator<<(ostream& os, const pair<F,S>& p) {
    os << "(" << p.first << "," << p.second << ")"; return os; }
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "["; for(const T& a: v){ os << a << ", "; } os << "]"; return os; }
template <typename K, typename V> ostream& operator<<(ostream& os, const map<K,V>& m) {
    os << "{"; for(const auto& p: m){ os << p.first <<":"<< p.second << ", "; } os << "]"; return os; }


LL uniq_ans = -1;


LL iabs(LL n){
    if(n < 0) return -n;
    return n;
}

bool bfs(LL pos, LL val, LL side, vector<LL>& memo, vector<LL>& val_memo, vector<vector<pair<LL, LL>>>& edge, pair<LL,LL>& left_range, pair<LL,LL>& right_range){
    if(memo[pos] >= 0){
        if(memo[pos] == side){
            return val_memo[pos] == val;
        }else{
            LL uniq_ans2 = iabs(val_memo[pos] - val);
            //cerr << "2 = " << val_memo[pos] << ", " << val<< endl;
            if(uniq_ans2 % 2 == 1) return false;
            if(uniq_ans == -1){
                uniq_ans = uniq_ans2 / 2;
            }else{
                if(uniq_ans != uniq_ans2 / 2) return false;
            }
            return true;
        }
    }
    memo[pos] = side;
    val_memo[pos] = val;
    if(side == 0){
        left_range.first = min<LL>(left_range.first, val);
        left_range.second = max<LL>(left_range.second, val);
    }else{
        right_range.first = min<LL>(right_range.first, val);
        right_range.second = max<LL>(right_range.second, val);
    }
    for(LL i = 0; i < edge[pos].size(); ++i){
        if(!bfs(edge[pos][i].first, edge[pos][i].second - val, 1-side, memo, val_memo, edge, left_range, right_range)) return false;
    }
    return true;
}

bool check(LL pos, LL val, vector<LL>& memo, vector<vector<pair<LL,LL>>>& edge){
    if(val < 0) return false;
    if(memo[pos] >= 0) return true;
    memo[pos] = 1;
    for(LL i = 0; i < edge[pos].size(); ++i){
        if(!check(edge[pos][i].first, edge[pos][i].second - val, memo, edge)) return false;
    }
    return true;
}

int main(){
    LL n, m;
    cin >> n >> m;
    vector<vector<pair<LL,LL>>> edge(n);
    for(LL i = 0; i < m; ++i){
        LL u, v, s;
        cin >> u >> v >> s;
        --u; --v;
        edge[u].emplace_back(v, s);
        edge[v].emplace_back(u, s);
    }
    vector<LL> memo(n, -1);
    vector<LL> val_memo(n, 0);
    pair<LL, LL> left_range(1e+18, 0);
    pair<LL, LL> right_range(1e+18, 0);
    LL ans = 0;
    if(!bfs(0, 0, 0, memo, val_memo, edge, left_range, right_range)){
        cerr << "debug1" << endl;
        cout << 0 << endl;
        return 0;
    }
    if(uniq_ans >= 0){
        cerr << "debug2" << endl;
        memo = vector<LL>(n, -1);
        if(check(0, uniq_ans, memo, edge)){
            cout << 1 << endl;
        }else{
            cout << 0 << endl;
        }
        return 0;
    }else{
        LL left = -left_range.first + 1;
        LL right = right_range.first - 1;
        cerr << "debug3 : " << left_range << ", " << right_range << ", " << left << ", " << right << endl;
        cout << max<LL>(0, right - left + 1) << endl;
        return 0;
    }
}



Measured memory_bytes: 20352