/*
ID: niepeng1
PROG: milk6
LANG: C++
*/
/*
简单的网络流问题,但是增加了求关键路径。
就是从出发点开始flood fill,注意只flood fill
那些非关键路径的边,就是flow<capa 或 反向flow
大于0的边。
很巧。
*/
#include<iostream>
#include<memory.h>
struct stru{
int f;
int t;
int value;
bool use;
}side[1000];
long long capa[40][40],flow[40][40],ans;
int i,n,m,pre[40],q[40];
bool vis[40];
inline long long min1(long long x,long long y){
return x<y?x:y;
}
bool Improvable()
{
int s,e,i;
memset(pre,-1,sizeof(pre));
q[0]=0;pre[0]=0;s=e=0;
while(s<=e){
for(i=0;i<n;i++){
if(pre[i]==-1&&(flow[q[s]][i]<capa[q[s]][i]||flow[i][q[s]]>0)){
pre[i]=q[s];
e++;
q[e]=i;
if(i==n-1) return true;
}
}
s++;
}
return false;
}
void Increase()
{
int now,t;
long long min=(long long)(1047483647)*2147483647;
now=n-1;
while(now){
t=pre[now];
if(flow[t][now]<capa[t][now])
min=min1(min,capa[t][now]-flow[t][now]);
else
if(flow[now][t]>0)
min=min1(min,flow[now][t]);
now=t;
}
now=n-1;
while(now){
t=pre[now];
if(flow[t][now]<capa[t][now])
flow[t][now]+=min;
else
if(flow[now][t]>0)
flow[now][t]-=min;
now=t;
}
}
long long MaxFlow()
{
int i;
long long ret=0;
while(Improvable())
Increase();
for(i=0;i<n;i++)
ret+=flow[0][i];
return ret;
}
void flood_fill(int now){
int i;
vis[now]=true;
for(i=0;i<n;i++)
if(!vis[i]&&(flow[now][i]<capa[now][i]||flow[i][now]>0))
flood_fill(i);
/*太巧了,不是关键路径,访问之*/
}
int main(){
freopen("milk6.in","r",stdin);
freopen("milk6.out","w",stdout);
scanf("%d%d",&n,&m);
memset(capa,0,sizeof(capa));
for(i=0;i<m;i++){
scanf("%d%d%d",&side[i].f,&side[i].t,&side[i].value);
side[i].f--;
side[i].t--;
side[i].use=false;
capa[side[i].f][side[i].t]+=(long long)500000*1001*side[i].value+500000+i;
/* ??? */
}
ans=MaxFlow();
printf("%lld %d/n",ans/(500000*1001),((ans%(500000*1001))/500000));
/* ??? */
memset(vis,false,sizeof(vis));
flood_fill(0);
for(i=0;i<m;i++)
if(vis[side[i].f]&&!vis[side[i].t])
printf("%d/n",i+1);
return 0;
}