// Slower C++ solution:
#include<cstdio>

#include<queue>

#include<vector>

#include<cstring>

#include<algorithm>

using namespace std;

typedef long long ll;

const int Maxn=1e5;

const ll INF=1e18;

struct Edge {

	int to;

	ll cost;

	Edge(int a,ll b){to=a,cost=b;}

};

vector<Edge> G[Maxn+4];

ll F[Maxn+5][2];

ll Root=-1,L=1,R=INF+5;

void AddEdge(int u,int v,ll w) {

	G[u].push_back(Edge(v,w));

}

int N,M;

bool vis[Maxn+5];

void BFS(int s) {

	queue<int> q;

	vis[s]=true;q.push(s);

	F[s][0]=1,F[s][1]=0;

	while(!q.empty()) {

		int u=q.front();q.pop();

		for(int i=0;i<G[u].size();i++) {

			int v=G[u][i].to;

			ll w=G[u][i].cost;

			if(vis[v])continue;

			F[v][0]=-F[u][0];

			F[v][1]=w-F[u][1];

			vis[v]=true;

			q.push(v);

		}

	}

}

int main() {

	#ifdef LOACL

	freopen("in.txt","r",stdin);

	freopen("out.txt","w",stdout);

	#endif

	scanf("%d %d",&N,&M);

	for(int i=1;i<=M;i++) {

		int u,v,w;

		scanf("%d %d %d",&u,&v,&w);

		AddEdge(u,v,w);

		AddEdge(v,u,w);

	}

	BFS(1);

	for(int i=1;i<=N;i++) {

		if(F[i][0]==1)L=max(L,1-F[i][1]);

		else R=min(R,F[i][1]-1);

		for(int j=0;j<G[i].size();j++) {

			int v=G[i][j].to;

			ll w=G[i][j].cost;

			ll x=F[i][0]+F[v][0];

			ll y=F[i][1]+F[v][1];

			if(x==0&&y!=w) {

				puts("0");

				return 0;

			}

			if(x!=0) {

				ll tmp=w-y;

				if(tmp%2||tmp/x<=0) {

					printf("0\n");

					return 0;

				}

				if(Root==-1)

					Root=tmp/x;

				if(Root!=tmp/x) {

					printf("0\n");

					return 0;

				}

			}

		}

	}

	if(Root==-1)

		printf("%d\n",max(0*1LL,R-L+1));

	else

		printf("%d\n",(L<=Root&&Root<=R));

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.3311078699206953x):
#include<iostream>

#include<cstdio>

#include<cstring>

#include<climits>

#include<algorithm>

#include<cmath>

#include<queue>

using namespace std;

#define MAXN 100000

#define MAXM 100000

#define INF 1000000000000000

struct node

{

    int next,to;

    long long w;

}e[MAXM*2+5];

struct Qr

{

    int xr,dec;

    long long lim;

};

long long T;

int cnt,m,n;

int x,y,z,flag;

long long ri=INF,le=-INF;

long long vis[2][MAXN+5];

int b[MAXN+5];

void fpush(int u,int v,long long w)

{

    e[++cnt].next=b[u];

    e[cnt].w=w;

    e[cnt].to=v;

    b[u]=cnt;

}

int Ch(int x){if(x==-1)x=0;return x;}

void dfs(int xr,int dec,long long lim)

{

    if(flag)return ;

    for(int i=b[xr];i;i=e[i].next)

    {

        int xnext=e[i].to;

        long long nlim=e[i].w-lim;

        int FD=Ch(dec);

        if(vis[FD][xnext]!=INF)

        {

            if(vis[FD][xnext]!=nlim){flag=1;return ;}

            else continue;

        }

        vis[FD][xnext]=nlim;

        if(!FD)le=max(le,-vis[FD][xnext]);

        else ri=min(ri,vis[FD][xnext]);

        dfs(xnext,-dec,nlim);

    }

}

int main()

{

    fill(vis[0],vis[0]+MAXN+1,INF);

    fill(vis[1],vis[1]+MAXN+1,INF);

    scanf("%d%d",&n,&m);

    for(int i=1;i<=m;i++)

    {

        scanf("%d%d%d",&x,&y,&z);

        fpush(x,y,z);fpush(y,x,z);

    }

    dfs(1,1,0);

    if(flag){printf("0\n");return 0;}

    long long T=-1;//

    for(int i=1;i<=n;i++)

        if(vis[0][i]!=INF&&vis[1][i]!=INF)

        {

            long long NT=(vis[1][i]-vis[0][i])/2;

            if(NT<0){flag=1;break;}

            if(T==-1)T=NT;

            else if(T!=NT){flag=1;break;}

        }

    if(flag){printf("0\n");return 0;}

    if(T!=-1)

    {

        if(T>le&&T<ri)printf("1\n");

        else printf("0\n");

    }

    else printf("%lld",max((long long)0,ri-le-1));

}