#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 2;
int n, m;
int viz[N], aux[N], c[N], id[N];
vector<int> meh;
vector<int> g[N];
vector<pair<int, int> > v[N];
bool Loop2(int x) {
  if (viz[x] == 1) return 1;
  if (viz[x] == 2) return 0;
  viz[x] = 1;
  for (auto &it : g[x]) {
    if (Loop2(it)) return 1;
  }
  viz[x] = 2;
  return 0;
}
bool Loop() {
  memset(viz, 0, sizeof(viz));
  for (int i = 1; i <= n; i++) {
    if (!viz[i] && Loop2(i)) return 1;
  }
  return 0;
}
int ok(int x) {
  for (int i = 1; i <= n; i++) {
    g[i].clear();
    for (auto it : v[i]) {
      if (c[it.second] > x) g[i].push_back(it.first);
    }
  }
  return !Loop();
}
void fake(int x) {
  priority_queue<int, vector<int>, greater<int> > pq;
  for (int i = 1; i <= n; i++)
    for (auto it : g[i]) aux[it]++;
  vector<int> topo;
  for (int i = 1; i <= n; i++) {
    if (!aux[i]) pq.push(i);
  }
  while (!pq.empty()) {
    int u = pq.top();
    pq.pop();
    topo.push_back(u);
    for (auto it : g[u]) {
      aux[it]--;
      if (!aux[it]) pq.push(it);
    }
  }
  int nr = 0;
  for (auto it : topo) id[it] = ++nr;
  for (int i = 1; i <= n; i++) {
    for (auto it : v[i]) {
      if (c[it.second] <= x && id[it.first] < id[i]) meh.push_back(it.second);
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int a, b;
    cin >> a >> b >> c[i];
    v[a].push_back({b, i});
  }
  int st = 0, dr = 1e9, ans;
  while (st <= dr) {
    int mid = (st + dr) / 2;
    if (ok(mid)) {
      dr = mid - 1;
      ans = mid;
    } else
      st = mid + 1;
  }
  ok(ans);
  fake(ans);
  cout << ans << " " << meh.size() << "\n";
  for (auto it : meh) cout << it << " ";
  return 0;
}
