#include <bits/stdc++.h>
using namespace std;
struct Edge {
  long long ind;
  long long u, v;
  long long w;
  bool operator<(const Edge &x) const { return w < x.w; }
};
const long long MAX_N = 1e5 + 10;
long long n, r;
Edge edge[MAX_N];
long long par[MAX_N];
set<long long> s;
bool mark[MAX_N];
vector<pair<long long, long long> > nei[MAX_N];
long long trees[MAX_N], size[MAX_N];
void upd(long long x, long long y);
long long dfs_size(long long v, long long p);
void dfs_tree(long long u, long long p);
long long root(long long v) {
  if (par[v] < 0) return v;
  par[v] = root(par[v]);
  return par[v];
}
bool merge(long long u, long long v) {
  u = root(u);
  v = root(v);
  if (u == v) return false;
  if (par[v] < par[u]) swap(u, v);
  par[u] += par[v];
  par[v] = u;
  return true;
}
int main() {
  cin >> n;
  for (long long i = 0; i < n - 1; ++i) {
    long long a, b, w;
    cin >> a >> b >> w;
    a--;
    b--;
    edge[i] = (Edge){i, a, b, w};
  }
  fill(par, par + n, -1);
  sort(edge, edge + n - 1);
  long long l = 0;
  for (long long i = 0; i < n; ++i) {
    if (i == n - 1 || edge[i].w != edge[l].w) {
      upd(l, i - 1);
      l = i;
    }
  }
  long long mx = *max_element(trees, trees + n - 1);
  long long cnt = count(trees, trees + n - 1, mx);
  cout << mx << " " << cnt << endl;
  for (long long i = 0; i < n - 1; ++i)
    if (trees[i] == mx) cout << i + 1 << endl;
  return 0;
}
void upd(long long x, long long y) {
  for (long long i = x; i < y + 1; ++i) {
    long long u = root(edge[i].u);
    long long v = root(edge[i].v);
    long long ind = edge[i].ind;
    s.insert(u);
    s.insert(v);
    nei[u].push_back(make_pair(v, ind));
    nei[v].push_back(make_pair(u, ind));
  }
  for (set<long long>::iterator it = s.begin(); it != s.end(); ++it) {
    long long u = *it;
    if (!mark[u]) dfs_size(u, -1);
  }
  for (set<long long>::iterator it = s.begin(); it != s.end(); ++it) {
    long long u = *it;
    mark[u] = 0;
  }
  for (set<long long>::iterator it = s.begin(); it != s.end(); ++it) {
    long long u = *it;
    if (!mark[u]) r = u, dfs_tree(u, -1);
  }
  for (set<long long>::iterator it = s.begin(); it != s.end(); ++it) {
    long long u = *it;
    mark[u] = 0;
    nei[u].clear();
  }
  for (long long i = x; i < y + 1; ++i) {
    merge(edge[i].u, edge[i].v);
  }
  s.clear();
}
long long dfs_size(long long v, long long p) {
  mark[v] = 1;
  size[v] = -par[v];
  for (long long i = 0; i < nei[v].size(); ++i) {
    long long u = nei[v][i].first;
    if (u != p) size[v] += dfs_size(u, v);
  }
  return size[v];
}
void dfs_tree(long long u, long long p) {
  mark[u] = 1;
  for (long long i = 0; i < nei[u].size(); ++i) {
    long long v = nei[u][i].first;
    long long ind = nei[u][i].second;
    if (v != p) {
      dfs_tree(v, u);
      trees[ind] += (size[v] * (size[r] - size[v])) * 2;
    }
  }
}
