#include <bits/stdc++.h>
using namespace std;
const long long INF = (long long)1e9;
const long long MAXN = (long long)3e5 + 100;
const long long MOD = (long long)1e9 + 7;
const long double EPS = (long double)1e-10;
long long power(long long x, long long n, long long mod = 1e9 + 7) {
  if (n == 0) return 1ll;
  if (n & 1ll) return power(x, n - 1ll, mod) * x % mod;
  long long tmp = power(x, n >> 1ll, mod);
  return (tmp * tmp) % mod;
}
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
template <class t1, class t2>
inline bool cmin(t1 &a, const t2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class t1, class t2>
inline bool cmax(t1 &a, const t2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
vector<vector<pair<long long, long long>>> g;
long long H[MAXN];
const long long alphabet = 26;
struct node {
  vector<node *> nxt;
  long long sz = 1;
  node() {
    nxt.resize(alphabet, nullptr);
    sz = 1;
  }
};
long long maxh = -INF;
void maketrie(node *cur, long long v, long long p = -1, long long h = 0) {
  cmax(maxh, h);
  cur->sz = 1;
  for (auto u : g[v]) {
    long long c = u.second;
    long long to = u.first;
    if (to == p) continue;
    if (!cur->nxt[c]) {
      cur->nxt[c] = new node();
    }
    maketrie(cur->nxt[c], to, v, h + 1);
    cur->sz += cur->nxt[c]->sz;
  }
}
vector<pair<node *, node>> mem;
long long w[MAXN];
long long ADDVERTEX = 0;
void merge(node *a, node *b) {
  for (long long c = 0; c < alphabet; c++) {
    if (a->nxt[c] != nullptr) {
      if (b->nxt[c] != nullptr) {
        merge(a->nxt[c], b->nxt[c]);
      } else {
        node copy = *b;
        mem.push_back({b, copy});
        b->nxt[c] = a->nxt[c];
        ADDVERTEX += a->nxt[c]->sz;
      }
    }
  }
}
void dfs(node *cur, long long h = 0) {
  long long old_sz = 0;
  node *M = nullptr;
  for (long long i = 0; i < alphabet; i++) {
    if (cur->nxt[i] != nullptr) {
      dfs(cur->nxt[i], h + 1);
    }
  }
  for (long long i = 0; i < alphabet; i++) {
    if (cur->nxt[i] != nullptr) {
      old_sz += cur->nxt[i]->sz;
      if (M == nullptr || M->sz < cur->nxt[i]->sz) M = cur->nxt[i];
    }
  }
  if (M == nullptr) return;
  mem.clear();
  ADDVERTEX = 0;
  for (long long i = 0; i < alphabet; i++) {
    if (cur->nxt[i] != nullptr && cur->nxt[i] != M) {
      merge(cur->nxt[i], M);
    }
  }
  long long new_sz = ADDVERTEX + M->sz - 1;
  for (long long i = (long long)mem.size() - 1; i >= 0; i--) {
    node *adr = mem[i].first;
    node old = mem[i].second;
    *adr = old;
  }
  mem.clear();
  w[h] += (new_sz - old_sz);
}
signed main() {
  iostream::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  mt19937 rnd(42);
  long long n;
  cin >> n;
  g.resize(n);
  for (long long i = 0; i < n - 1; i++) {
    long long u, v;
    char c;
    cin >> u >> v >> c;
    u--;
    v--;
    g[u].push_back({v, c - 'a'});
    g[v].push_back({u, c - 'a'});
  }
  node *root = new node();
  maketrie(root, 0);
  dfs(root);
  long long id = -1;
  long long M = INF;
  for (long long i = 0; i < maxh; i++) {
    if (w[i] < M) {
      id = i;
      M = w[i];
    }
  }
  cout << n + M << "\n";
  cout << id + 1 << "\n";
}
