#include <cstddef>
#include <queue>
#include <cassert>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
namespace loquat {
using vertex_t = size_t;
}
namespace loquat {
namespace edge_param {
struct to_ {
	vertex_t to;
	explicit to_(vertex_t t = 0)
		: to(t)
	{ }
};
template <typename T>
struct weight_ {
	using weight_type = T;
	weight_type weight;
	explicit weight_(const weight_type& w = weight_type())
		: weight(w)
	{ }
};
template <typename T>
using weight = weight_<T>;
}
namespace detail {
template <typename T, typename... Params>
struct edge_param_wrapper : public T, edge_param_wrapper<Params...> {
	template <typename U, typename... Args>
	explicit edge_param_wrapper(U&& x, Args&&... args)
		: T(std::forward<U>(x))
		, edge_param_wrapper<Params...>(std::forward<Args>(args)...)
	{ }
};
template <typename T>
struct edge_param_wrapper<T> : public T {
	template <typename U>
	explicit edge_param_wrapper(U&& x)
		: T(std::forward<U>(x))
	{ }
};
}
template <typename... Params>
struct edge : public detail::edge_param_wrapper<edge_param::to_, Params...> {
	template <typename... Args>
	explicit edge(Args&&... args)
		: detail::edge_param_wrapper<edge_param::to_, Params...>(
			std::forward<Args>(args)...)
	{ }
};
}
namespace loquat {
template <typename EdgeType>
class adjacency_list {
public:
	using edge_type = EdgeType;
	using edge_list = std::vector<edge_type>;
private:
	std::vector<std::vector<EdgeType>> m_edges;
public:
	explicit adjacency_list(size_t n)
		: m_edges(n)
	{ }
	edge_list& operator[](vertex_t u){
		return m_edges[u];
	}
	template <typename... Args>
	void add_edge(vertex_t from, Args&&... args){
		m_edges[from].emplace_back(std::forward<Args>(args)...);
	}
};
}
using namespace std;
using ll = long long;
using edge = loquat::edge<loquat::edge_param::weight<int>>;
static ll INF = 1000000000000000000ll;
int main(){
	ios_base::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	loquat::adjacency_list<edge> g(n);
	for(int i = 0; i < m; ++i){
		int u, v, s;
		cin >> u >> v >> s;
		--u; --v;
		g.add_edge(u, v, s);
		g.add_edge(v, u, s);
	}
	int root = -1;
	ll init = 0;
	vector<int> oe(n, 0);
	vector<ll> values(n, 0);
	{
		queue<int> q;
		oe[0] = 1;
		values[0] = 0;
		q.push(0);
		while(!q.empty()){
			const int u = q.front();
			q.pop();
			for(const auto& e : g[u]){
				const int v = e.to;
				const ll s = e.weight;
				if(oe[v] == 0){
					oe[v] = -oe[u];
					values[v] = s - values[u];
					q.push(v);
				}
			}
		}
	}
	for(int u = 0; u < n; ++u){
		for(const auto& e : g[u]){
			const int v = e.to;
			const ll s = e.weight;
			if(oe[u] == oe[v]){
				const ll t = s - values[u] - values[v];
				if(t % 2 != 0){
					cout << 0 << endl;
					return 0;
				}
				root = u;
				init = values[u] + t / 2;
			}else if(s != values[u] + values[v]){
				cout << 0 << endl;
				return 0;
			}
		}
	}
	if(root < 0){
		ll pmin = INF, pmax = -INF;
		ll nmin = INF, nmax = -INF;
		for(int i = 0; i < n; ++i){
			if(oe[i] == 1){
				pmin = min(pmin, values[i]);
				pmax = max(pmax, values[i]);
			}else{
				nmin = min(nmin, values[i]);
				nmax = max(nmax, values[i]);
			}
		}
		const ll offset = 1 - pmin;
		pmin += offset; pmax += offset;
		nmin -= offset; nmax -= offset;
		cout << max<ll>(0, nmin) << endl;
		return 0;
	}else{
		oe.assign(n, 0);
		values.assign(n, 0);
		queue<int> q;
		oe[root] = 1;
		values[root] = init;
		q.push(root);
		while(!q.empty()){
			const int u = q.front();
			q.pop();
			for(const auto& e : g[u]){
				const int v = e.to;
				const ll s = e.weight;
				if(oe[v] != 0){
					if(values[u] + values[v] != s){
						cout << 0 << endl;
						return 0;
					}
				}else{
					oe[v] = -oe[u];
					values[v] = s - values[u];
					q.push(v);
				}
			}
		}
		if(*min_element(values.begin(), values.end()) <= 0){
			cout << 0 << endl;
		}else{
			cout << 1 << endl;
		}
	}
	return 0;
}


Measured memory_bytes: 9216