#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:16777216")
using namespace std;
struct Node {
  int key, prior;
  int cnt;
  int num;
  vector<pair<int, int> > vid;
  Node *l, *r;
  Node() {}
  Node(int k, int p, int v, int id) {
    key = k, prior = p, cnt = num = 1, l = r = NULL;
    vid.push_back(pair<int, int>(v, id));
  }
};
struct Edge {
  int b, d, id;
};
int n;
vector<Edge> g[100000];
long long nice;
vector<int> niceid;
int dp[100000];
Node* Root;
int rnd[100000], rc;
int cnt(Node* t) { return t ? t->cnt : 0; }
void updcnt(Node* t) {
  if (t) t->cnt = t->num + cnt(t->l) + cnt(t->r);
}
void split(Node* t, int key, Node*& l, Node*& r) {
  if (!t)
    l = r = NULL;
  else if (key <= t->key)
    split(t->l, key, l, t->l), r = t;
  else
    split(t->r, key, t->r, r), l = t;
  updcnt(t);
}
Node* unite(Node* l, Node* r) {
  if (!l || !r) {
    Node* t = l ? l : r;
    updcnt(t);
    return t;
  }
  if (l->prior < r->prior) swap(l, r);
  Node *lt, *tmp, *mt, *rt;
  split(r, l->key, lt, tmp);
  split(tmp, l->key + 1, mt, rt);
  if (mt && (mt->l || mt->r)) throw 1;
  if (mt) {
    for (int i = 0, _n = ((int)((mt->vid).size())); i < _n; ++i)
      l->vid.push_back(mt->vid[i]);
    l->num += mt->num;
    updcnt(l);
  }
  l->l = unite(l->l, lt);
  l->r = unite(l->r, rt);
  updcnt(l);
  return l;
}
bool insertExists(Node* t, Node* it) {
  if (!t) return false;
  if (t->key == it->key) {
    t->vid.push_back(it->vid[0]);
    t->num++;
    updcnt(t);
    return true;
  }
  if (insertExists(it->key < t->key ? t->l : t->r, it)) {
    updcnt(t);
    return true;
  }
  return false;
}
void insertSplit(Node*& t, Node* it) {
  if (!t)
    t = it;
  else if (it->prior > t->prior)
    split(t, it->key, it->l, it->r), t = it;
  else
    insertSplit(it->key < t->key ? t->l : t->r, it);
  updcnt(t);
}
void insert(Node*& t, Node* it) {
  if (!insertExists(t, it)) insertSplit(t, it);
}
int count_lower_equals(Node* t, int val) {
  if (!t) return 0;
  if (t->key > val) return count_lower_equals(t->l, val);
  return t->num + cnt(t->l) + count_lower_equals(t->r, val);
}
void find_answers(Node* t, Node* root) {
  if (!t) return;
  find_answers(t->l, root);
  find_answers(t->r, root);
  for (int i = 0, _n = ((int)((t->vid).size())); i < _n; ++i) {
    int key = t->key;
    int v = t->vid[i].first;
    int id = t->vid[i].second;
    long long glob = count_lower_equals(root, key);
    long long cntup = glob - dp[v] - 1;
    long long cnt = 2 * (cntup + 1) * (dp[v] + 1);
    if (cnt > nice) {
      nice = cnt;
      niceid.clear();
      niceid.push_back(id);
    } else if (cnt == nice)
      niceid.push_back(id);
  }
}
void updateTree(Node*& t, int val) {
  if (!t) return;
  Node *lt, *rt;
  split(t, val, lt, rt);
  if (lt) {
    find_answers(lt, lt);
    lt->key = val;
    lt->l = NULL;
    lt->r = NULL;
    lt->vid.clear();
    lt->num = lt->cnt;
    updcnt(lt);
    t = unite(lt, rt);
  } else
    t = rt;
}
Node* dfs(int v, int par, int val, int id) {
  Node* root = NULL;
  for (int i = 0, _n = ((int)((g[v]).size())); i < _n; ++i)
    if (g[v][i].b != par) {
      Node* t = dfs(g[v][i].b, v, g[v][i].d, g[v][i].id);
      root = unite(root, t);
    }
  if (par != -1) {
    dp[v] = count_lower_equals(root, val);
    updateTree(root, val);
    insert(root, new Node(val, rnd[rc++], v, id));
    printf("");
  }
  return root;
}
void solution() {
  scanf("%d", &n);
  for (int i = 0, _n = (n - 1); i < _n; ++i) {
    int a, b, d;
    scanf("%d %d %d", &a, &b, &d);
    Edge A = {b - 1, d, i};
    Edge B = {a - 1, d, i};
    g[a - 1].push_back(A);
    g[b - 1].push_back(B);
  }
  for (int i = 0, _n = (n); i < _n; ++i) rnd[i] = i;
  random_shuffle(rnd, rnd + n);
  Root = dfs(0, -1, -1, -1);
  find_answers(Root, Root);
  sort((niceid).begin(), (niceid).end());
  printf("%I64d %d\n", nice, (int)((niceid).size()));
  for (int i = 0, _n = ((int)((niceid).size())); i < _n; ++i)
    printf("%d ", niceid[i] + 1);
  putchar('\n');
}
int main() {
  solution();
  return 0;
}
