#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
using ll = long long;
using uint = unsigned int;
struct Edge {
  int from, to, cost;
};
const int N = 1e5;
vector<Edge> g[N + 1];
int color[N + 1];
int tout[N + 1];
int timer;
bool dfs(int v, int bound) {
  if (color[v] != 0) {
    return color[v] == 2;
  }
  color[v] = 1;
  for (auto& e : g[v]) {
    if (e.cost > bound && !dfs(e.to, bound)) {
      return false;
    }
  }
  color[v] = 2;
  ++timer;
  tout[v] = timer;
  return true;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  vector<Edge> edges(m);
  for (int i = 0; i < m; ++i) {
    int u, v, c;
    cin >> u >> v >> c;
    g[u].push_back({u, v, c});
    edges[i] = {u, v, c};
  }
  int l = -1;
  int r = 1e9;
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    timer = 0;
    fill_n(color + 1, n, 0);
    for (int v = 1; v <= n; ++v) {
      if (!dfs(v, mid)) {
        l = mid;
      }
    }
    if (l < mid) {
      r = mid;
    }
  }
  timer = 0;
  fill_n(color + 1, n, 0);
  for (int v = 1; v <= n; ++v) {
    dfs(v, r);
  }
  vector<int> ans;
  for (int i = 0; i < m; ++i) {
    if (tout[edges[i].from] < tout[edges[i].to]) {
      ans.push_back(i + 1);
    }
  }
  cout << r << ' ' << ans.size() << '\n';
  for (int x : ans) {
    cout << x << ' ';
  }
  return 0;
}
