#include <bits/stdc++.h>
const int N = 100010;
struct Edge {
  int to, next, v;
} edge[N];
struct E {
  int to, next;
} e[N];
struct P {
  int u, v, w;
} Protuct[N];
int h[N], s;
int du[N];
int head[N], sum;
int n, m;
int DFN[N];
inline void add(int x, int y, int z) {
  edge[++sum].to = y;
  edge[sum].v = z;
  edge[sum].next = head[x];
  head[x] = sum;
  return;
}
inline void add2(int x, int y) {
  e[++s].to = y;
  e[s].next = h[x];
  h[x] = s;
  return;
}
inline bool check(int v) {
  s = 0;
  memset(e, 0, sizeof(e));
  memset(h, 0, sizeof(h));
  memset(du, 0, sizeof(du));
  for (register int i = 1; i <= n; ++i) {
    for (register int j = head[i]; j; j = edge[j].next) {
      if (edge[j].v > v) {
        add2(i, edge[j].to);
        ++du[edge[j].to];
      }
    }
  }
  std::queue<int> q;
  while (!q.empty()) q.pop();
  int qwq = 0;
  for (register int i = 1; i <= n; ++i) {
    if (!du[i]) q.push(i);
  }
  while (!q.empty()) {
    int i = q.front();
    q.pop();
    ++qwq;
    DFN[i] = qwq;
    for (register int j = h[i]; j; j = e[j].next) {
      --du[e[j].to];
      if (!du[e[j].to]) q.push(e[j].to);
    }
  }
  if (qwq == n) return true;
  return false;
}
int main(void) {
  scanf("%d%d", &n, &m);
  int Maxvge = -1;
  for (register int i = 1; i <= m; ++i) {
    int x, y, z;
    scanf("%d%d%d", &x, &y, &z);
    add(x, y, z);
    Maxvge = std::max(Maxvge, z);
    Protuct[i].u = x, Protuct[i].v = y, Protuct[i].w = z;
  }
  int l = 0, r = Maxvge;
  int ans;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
      ans = mid;
      r = mid - 1;
    } else {
      l = mid + 1;
    }
  }
  check(ans);
  int k = 0;
  printf("%d ", ans);
  for (register int i = 1; i <= m; ++i) {
    if (DFN[Protuct[i].u] > DFN[Protuct[i].v] && Protuct[i].w <= ans) {
      ++k;
    }
  }
  printf("%d\n", k);
  for (register int i = 1; i <= m; ++i) {
    if (DFN[Protuct[i].u] > DFN[Protuct[i].v] && Protuct[i].w <= ans) {
      printf("%d ", i);
    }
  }
  return 0;
}
