#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
struct Edge {
  int u, v, c;
} e[N];
vector<int> g[N];
int n, m, cnt, cur[N], indegree[N];
bool topo(int c) {
  for (int i = 1; i <= n; i++) {
    g[i].clear();
    indegree[i] = cur[i] = 0;
  }
  int node_num = 0;
  for (int i = 1; i <= m; i++)
    if (e[i].c > c) {
      g[e[i].u].emplace_back(e[i].v);
      indegree[e[i].v]++;
    }
  memset(cur, 0, sizeof(cur));
  queue<int> q;
  for (int i = 1; i <= n; i++)
    if (!indegree[i]) q.push(i);
  cnt = 0;
  int count = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    cur[u] = ++cnt;
    count++;
    for (auto& v : g[u]) {
      if (--indegree[v] == 0) {
        q.push(v);
      }
    }
  }
  for (int i = 1; i <= n; i++)
    if (indegree[i]) return false;
  return true;
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v >> e[i].c;
  int l = 0, r = 1e9;
  while (l < r) {
    int mid = (l + r) >> 1;
    if (topo(mid))
      r = mid;
    else
      l = mid + 1;
  }
  topo(r);
  vector<int> ans;
  for (int i = 1; i <= m; i++)
    if (e[i].c <= r && cur[e[i].u] > cur[e[i].v]) ans.push_back(i);
  cout << r << " " << ans.size() << '\n';
  for (auto& item : ans) cout << item << " ";
  cout << '\n';
  return 0;
}
