#include <bits/stdc++.h>
using namespace std;
const long long max_n = 2e5 + 100;
long long n;
vector<pair<long long, long long> > adj[max_n];
long long S[max_n];
vector<long long> G[max_n];
struct Edge {
  long long x, y, w, idx;
  Edge() {}
  Edge(long long x, long long y, long long w, long long idx)
      : x(x), y(y), w(w), idx(idx) {}
};
Edge edges[max_n];
class Disjoint_Sets {
 public:
  long long* parent;
  long long* size;
  Disjoint_Sets() {}
  Disjoint_Sets(long long n) {
    parent = new long long[n];
    size = new long long[n];
    for (long long i = 0; i < n; i++) {
      parent[i] = i;
      size[i] = 1;
    }
  }
  void merge(long long a, long long b) {
    long long parent_a = find(a);
    long long parent_b = find(b);
    if (parent_a == parent_b) return;
    if (size[parent_a] < size[parent_b]) {
      parent[parent_a] = parent_b;
      size[parent_b] += size[parent_a];
      size[parent_a] = 0;
    } else {
      parent[parent_b] = parent_a;
      size[parent_a] += size[parent_b];
      size[parent_b] = 0;
    }
  }
  long long find(long long a) {
    if (parent[a] == a) {
      return a;
    }
    parent[a] = find(parent[a]);
    return parent[a];
  }
};
long long st[max_n];
long long total[max_n];
Disjoint_Sets D;
long long get_st(long long v, long long p) {
  if (st[v] != -1) return st[v];
  st[v] = D.size[v];
  for (long long x : G[v])
    if (x != p) {
      get_st(x, v);
      st[v] += st[x];
    }
  return st[v];
}
void update_total(long long v, long long p, long long T) {
  total[v] = T;
  for (long long x : G[v])
    if (x != p) {
      update_total(x, v, T);
    }
}
long long ans[max_n];
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  memset(st, -1, sizeof(st));
  memset(total, -1, sizeof(total));
  cin >> n;
  D = Disjoint_Sets(n);
  for (long long i = 0; i < n - 1; i++) {
    long long x, y, w;
    cin >> x >> y >> w;
    x--;
    y--;
    adj[x].push_back({y, w});
    adj[y].push_back({x, w});
    edges[i] = Edge(x, y, w, i);
  }
  sort(edges, edges + n - 1,
       [](const Edge& a, const Edge& b) -> bool { return a.w < b.w; });
  long long i = 0;
  while (i < n - 1) {
    long long j = i;
    while (j < n - 1 && edges[i].w == edges[j].w) {
      j++;
    }
    for (long long k = i; k < j; k++) {
      G[D.find(edges[k].x)].push_back(D.find(edges[k].y));
      G[D.find(edges[k].y)].push_back(D.find(edges[k].x));
    }
    for (long long k = i; k < j; k++) {
      long long u = D.find(edges[k].x);
      long long v = D.find(edges[k].y);
      if (st[u] == -1) {
        get_st(u, -1);
        update_total(u, -1, st[u]);
      }
      long long X = min(st[u], st[v]);
      long long Y = total[u] - X;
      ans[edges[k].idx] = (2 * X * Y);
    }
    for (long long k = i; k < j; k++) {
      long long u = D.find(edges[k].x);
      long long v = D.find(edges[k].y);
      G[u].clear();
      G[v].clear();
      st[u] = -1;
      st[v] = -1;
      total[u] = -1;
      total[v] = -1;
      D.merge(u, v);
    }
    i = j;
  }
  long long maxi = *max_element(ans, ans + n - 1);
  vector<long long> final;
  for (long long i = 0; i < n - 1; i++)
    if (ans[i] == maxi) {
      final.push_back(i);
    }
  cout << maxi << " " << final.size() << "\n";
  for (long long x : final) {
    cout << x + 1 << " ";
  }
  cout << "\n";
}
