#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9 + 5;
int read(int &a) {
  scanf("%d", &a);
  return a;
}
int read() {
  int a;
  scanf("%d", &a);
  return a;
}
int read(int &a, int &b) {
  scanf("%d %d", &a, &b);
  return a;
}
struct edge {
  int u, v, c;
  edge(int u = 0, int v = 0, int c = 0) : u(u), v(v), c(c) {}
} edges[N];
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    pq;
int n, m;
int val[N];
int vis[N];
int done[N];
int u, v, c;
int valp[N];
vector<int> G[N];
void reval(int s) {
  while (valp[s] < G[s].size() &&
         (done[G[s][valp[s]]] || edges[G[s][valp[s]]].u == s)) {
    valp[s]++;
  }
  if (valp[s] == G[s].size())
    val[s] = 0;
  else
    val[s] = edges[G[s][valp[s]]].c;
}
vector<int> road;
int s;
int ans = 0;
int cnt = 0;
bool cmp(int a, int b) { return edges[a].c > edges[b].c; }
int main() {
  read(n, m);
  for (int i = 1; i <= m; i++) {
    read(u, v);
    read(c);
    edges[i] = edge(u, v, c);
    G[u].push_back(i);
    G[v].push_back(i);
  }
  int p;
  for (int i = 1; i <= n; i++) {
    sort(G[i].begin(), G[i].end(), cmp);
    reval(i);
    pq.push(pair<int, int>(val[i], i));
  }
  pair<int, int> x;
  while (!pq.empty()) {
    x = pq.top();
    pq.pop();
    s = x.second;
    if (vis[s]) continue;
    vis[s] = 1;
    for (int j = 0; j < G[s].size(); j++) {
      p = G[s][j];
      if (done[p]) {
        continue;
      }
      done[p] = 1;
      u = edges[p].u;
      v = edges[p].v;
      c = edges[p].c;
      if (u != s) {
        pq.push(pair<int, int>(val[u], u));
        road.push_back(p);
        ans = max(ans, c);
      } else {
        if (c == val[v]) reval(v);
        pq.push(pair<int, int>(val[v], v));
      }
    }
  }
  cnt = road.size();
  printf("%d %d\n", ans, cnt);
  for (int i = 0; i < road.size(); i++) printf("%d ", road[i]);
  return 0;
}
