/*Bismillahir Rahmanir Rahim*///{
#include <bits/stdc++.h>
#include <ext/numeric>
using namespace std; using __gnu_cxx::power;
using ll = long long; using ull = unsigned long long; using ld = long double;
const ll llinf = (1ll<<61)-1;
const double eps = 1e-6, ldeps = 1e-9;
struct Dbg {
static constexpr auto &os = cout;   // replace by cerr in interactive.
template<class C> static auto dud(C *x)->decltype(os << *x, 0);
template<class C> static char dud(...);
template<class C> typename enable_if<sizeof dud<C>(0)!=1, Dbg&>::type operator<<(const C &x) { os << x; return *this; }
template<class C> Dbg &dump(C b, C e) {
    *this << "\n[";
    int cur = 0;
    for (C i = b; i!=e and cur<26; i++, cur++) *this << ", "+2*(i==b) << *i;
    return *this << ']';
}
template<class C> typename enable_if<sizeof dud<C>(0)==1, Dbg&>::type operator<<(const C &x) {
    return dump(begin(x), end(x));
}
template<class C, size_t X> typename enable_if<!is_same<C, const char>::value, Dbg&>::type operator <<(C (&x)[X]) {
    return dump(begin(x), end(x));
}
template<class B, class C> Dbg &operator <<(const pair<B, C> &x) {
    return *this << '{' << x.first << ", " << x.second << '}';
}
Dbg &operator<<(ostream&(*x)(std::ostream&)) { os << x; return *this; }
} dbg;
void err(istringstream *iss) { delete iss; }
template<class C, class... Args> void err(istringstream *iss, const C &val, const Args &... args) {
    string name; *iss >> name; if (name.back()==',') name.pop_back();
    dbg << name << " = " << val << "; ", err(iss, args...);
}
#define bug(args...) dbg << __LINE__ << ": ", err(new istringstream(#args), args), dbg << endl
#define cbug(a, args...) if (a) bug(args);
#define ASSERT(a, o, b, args...) if (!((a)o(b))) bug(a, b, ##args), assert((a)o(b));
#define sl(a) int(strlen(a))
#define sz(a) int(a.size())
int T, Q, cn;//}
const int inf = 1000000007, mxn = 100005;

int n, m, mx[mxn], mn[mxn], par[mxn], de[mxn];
ll val[mxn];
list<pair<int, int> > g[mxn];

bitset<mxn> vstd, inStack;

void dfsCheck(const int &u) {
    if (val[u] <= 0) cout << "0\n", exit(0);
    for (auto &i : g[u]) {
        int v = i.first;
        if (!val[v]) val[v] = i.second-val[u], dfsCheck(v);
        else if (val[u]+val[v] != i.second) cout << "0\n", exit(0);
    }
}

void dfsRing(const int &u, const int &p) {
    vstd[u] = 1, inStack[u] = 1, par[u] = p;
    int v;
    for (auto &i : g[u]) if (v = i.first, v != p) {
        if (!vstd[v]) de[v] = i.second, dfsRing(v, u);
        else if (inStack[v]) {
            int x = u;
            ll sum = 0;
            bool odd = 1;
            while (x != v) sum += odd ? -de[x] : de[x], odd = !odd, x = par[x];
            if (!odd) {
                if (sum+i.second) cout << "0\n", exit(0);
            } else {
                // sum + 2*val[u] == i.second ==>
                val[u] = (i.second-sum)>>1;
                if (val[u] < 0 or sum+2*val[u] != i.second) cout << "0\n", exit(0);
                dfsCheck(u);
                cout << "1\n", exit(0);
            }
        }
    }
    inStack[u] = 0;
}

void dfs(const int &u, const int &p) {
    mx[u] = inf, mn[u] = 1;
    int v;
    for (auto &i : g[u]) if (v = i.first, v!=p) {
        dfs(v, u);
        mn[u] = max(mn[u], i.second-mx[v]), mx[u] = min(mx[u], i.second-mn[v]);
    }
    if (mx[u] < mn[u]) cout << "0\n", exit(0);
}



// ******************************************
// *** fill_n(lvl, n+1, inf), when needed ***
// ******************************************
int q[mxn], qh, qt, lvl[mxn];
void bfs(int src) {
    qh = qt = 0;
    lvl[src] = 0, q[qt++] = src;
    while (qh<qt) {
        int u = q[qh++], v;
        for (auto &i : g[u]) if (v = i.first, lvl[v]>lvl[u]+1) {
            lvl[v] = lvl[u]+1, q[qt++] = v;
        }
    }
}


bool dfsCheck2(int u, bool t) {
    if (val[u] <= 0 and (lvl[u]&1) == t) return 0;
    for (auto &i : g[u]) {
        int v = i.first;
        if (!val[v] and !(val[v] = i.second-val[u], dfsCheck2(v, t))) return 0;
        else if (val[u]+val[v] != i.second) cout << "0\n", exit(0);
    }
    return 1;
}


signed main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cout.precision(11);
/*
odd cycle => values of that cycle are uniquely identifiable ==> answer 1 or 0.
Tree => Maybe using a dp like approach, we can find for root its max possible value and min possible value.
even cycle => Only feasible way I can think of is binary search. As every pair of nodes' distance's parity is fixed,
we can do a binary search on val[1] and check whether it needs to be increased or decreased.
*/
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({v, w}), g[v].push_back({u, w});
    }

    if (m != n-1) {
        dfsRing(1, 0);
        fill_n(lvl, n+1, inf), bfs(1);
        int lo = 1, hi = inf, l = -1, r = -2;
        while (lo<=hi) {
            auto mid = (lo+hi)>>1;
            if (memset(val, 0, sizeof(val)), val[1] = mid, dfsCheck2(1, 0)) hi = mid-1, l = mid;
            else lo = mid+1;
        }
        lo = 1, hi = inf;
        while (lo<=hi) {
            auto mid = (lo+hi)>>1;
            if (memset(val, 0, sizeof(val)), val[1] = mid, dfsCheck2(1, 1)) lo = mid+1, r = mid;
            else hi = mid-1;
        }
        return cout << r-l+1 << '\n', 0;
    }
    dfs(1, 0);
    cout << mx[1]-mn[1]+1 << '\n';
}

Measured memory_bytes: 18048