#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#define INF 65535
#define MAXV 105
using namespace std;
int n,m,indegree[MAXV];
int flex[MAXV][MAXV];
struct ENode
{
int w,weight;
ENode(int _w, int _weight) : w(_w), weight(_weight) {}
};
vector<ENode> Adj[MAXV];
struct GNode
{
int earliest,latest;
}G[MAXV];
void topsort()
{
int v,u, cnt = 0, tlp = -1;
queue<int> q;
stack<int> s;
for(v=1; v<=n; v++)
{
if(indegree[v]==0)
{
q.push(v);
G[v].earliest = 0;
}
}
while(!q.empty())
{
u = q.front(); q.pop(); s.push(u); cnt++;
for(vector<ENode>::iterator it = Adj[u].begin(); it!=Adj[u].end(); it++)
{
indegree[it->w]--;
if((indegree[it->w])==0) q.push(it->w);
if(G[it->w].earliest < G[u].earliest+it->weight)
{
G[it->w].earliest = G[u].earliest+it->weight;
}
}
}
if(cnt != n) { printf("0\n"); return; }
for(v=1; v<=n; v++)
{
if(G[v].earliest > tlp)
tlp = G[v].earliest;
}
printf("%d\n",tlp);
for(v=1; v<=n; v++)
{
if(G[v].earliest == tlp)
{
G[v].latest = tlp;
}
}
while(!s.empty())
{
u = s.top(); s.pop(); //printf("u = s.top() = %d\n",u);
for(auto it = Adj[u].begin(); it!=Adj[u].end(); it++)
{
//printf("G[%d].latest = %d, it->weight = %d, G[%d].latest = %d\n",it->w,G[it->w].latest,it->weight,u,G[u].latest);
if(G[it->w].latest - it->weight < G[u].latest)
{
G[u].latest = G[it->w].latest - it->weight;
//printf("G[%d].latest = %d\n",u,G[u].latest);
}
}
}
for(v=1; v<=n; v++)
{
for(vector<ENode>::iterator it = Adj[v].begin(); it != Adj[v].end(); it++)
{
flex[v][it->w] = G[it->w].latest - G[v].earliest - it->weight;
}
}
for(v=1; v<=n; v++)
{
for(vector<ENode>::iterator it = Adj[v].begin(); it!=Adj[v].end(); it++)
{
//printf("flex[%d][%d] = %d\n",v,it->w,flex[v][it->w]);
if(flex[v][it->w] == 0)
printf("%d->%d\n",v,it->w);
}
}
}
int main()
{
int i,v1,v2,weight,v;
fill(indegree,indegree+MAXV,0);
fill(flex[0],flex[0]+MAXV*MAXV,-1);
scanf("%d%d",&n,&m);
for(v=1; v<=n; v++)
{
G[v].earliest = -1;
G[v].latest = INF;//printf("G[%d].latest = %d\n",v,G[v].latest);
}
//printf("G[5].latest = %d\n",G[5].latest);
for(i=0; i<m; i++)
{
scanf("%d%d%d",&v1,&v2,&weight);
Adj[v1].insert(Adj[v1].begin(),ENode(v2,weight));
indegree[v2]++;
}
topsort();
return 0;
}