#include <bits/stdc++.h>
using namespace std;
const long long oo = 0x3f3f3f3f;
const double eps = 1e-9;
const long long maxn = 100010;
struct edge {
  long long u, v, w, idx;
  bool operator<(const edge &e) const { return w < e.w; }
};
struct disjoint_set {
  long long n;
  vector<long long> ds;
  disjoint_set(long long n) : n(n) { ds = vector<long long>(n, -1); }
  long long root(long long a) { return ds[a] < 0 ? a : ds[a] = root(ds[a]); }
  bool join(long long u, long long v) {
    u = root(u), v = root(v);
    if (u == v) return true;
    if (ds[u] > ds[v]) swap(u, v);
    ds[u] += ds[v];
    ds[v] = u;
    return true;
  }
  long long size(long long u) { return -ds[root(u)]; }
};
struct tree {
  struct node {
    long long value;
    vector<pair<long long, long long>> adj;
  };
  int n;
  vector<node> nodes;
  vector<long long> children;
  vector<bool> marked;
  vector<int> c_dfs;
  tree(int n) : n(n) {
    nodes = vector<node>(n);
    children = vector<long long>(n);
    marked = vector<bool>(n);
  }
  void add_edge(int u, int v, long long uu, long long vv, long long idx) {
    nodes[u].value = uu;
    nodes[u].adj.push_back({v, idx});
    nodes[v].value = vv;
    nodes[v].adj.push_back({u, idx});
  }
  void dfs(long long u) {
    children[u] = nodes[u].value;
    marked[u] = true;
    c_dfs.push_back(u);
    for (auto v : nodes[u].adj) {
      if (!marked[v.first]) {
        dfs(v.first);
        children[u] += children[v.first];
      }
    }
  }
  map<long long, long long> solve() {
    map<long long, long long> ans;
    for (int i = 0; i < n; ++i) {
      if (marked[i]) continue;
      c_dfs.clear();
      dfs(i);
      long long total = children[i];
      for (auto u : c_dfs) {
        for (auto e : nodes[u].adj) {
          long long v = e.first, idx = e.second;
          long long m = min(children[u], children[v]);
          long long trees = m * (total - m);
          ans[idx] = trees;
        }
      }
    }
    return ans;
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long n;
  cin >> n;
  vector<edge> E(n - 1);
  disjoint_set ds(n + 1);
  for (long long i = 0; i < n - 1; ++i) {
    cin >> E[i].u >> E[i].v >> E[i].w;
    E[i].idx = i;
  }
  sort(E.begin(), E.end());
  vector<long long> ans(n - 1);
  for (long long i = 0, j; i < n - 1; i = j) {
    vector<pair<long long, long long>> to_join;
    vector<int> cand;
    for (j = i; j < n - 1 && E[j].w == E[i].w; ++j) {
      int u = E[j].u, v = E[j].v;
      cand.push_back(ds.root(u));
      cand.push_back(ds.root(v));
    }
    sort(cand.begin(), cand.end());
    cand.resize(unique(cand.begin(), cand.end()) - cand.begin());
    tree T(cand.size());
    for (j = i; j < n - 1 && E[j].w == E[i].w; ++j) {
      long long u = E[j].u, v = E[j].v, idx = E[j].idx;
      u = ds.root(u), v = ds.root(v);
      int iu = lower_bound(cand.begin(), cand.end(), u) - cand.begin();
      int iv = lower_bound(cand.begin(), cand.end(), v) - cand.begin();
      long long uu = ds.size(u), vv = ds.size(v);
      T.add_edge(iu, iv, uu, vv, idx);
      to_join.push_back({u, v});
    }
    for (auto r : T.solve()) {
      ans[r.first] = r.second;
    }
    for (auto p : to_join) ds.join(p.first, p.second);
  }
  long long M = *max_element(ans.begin(), ans.end());
  vector<long long> valid;
  for (long long i = 0; i < n - 1; ++i)
    if (ans[i] == M) valid.push_back(i + 1);
  cout << 2 * M << " " << valid.size() << endl;
  for (auto a : valid) cout << a << " ";
  cout << endl;
  return 0;
}
