#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;
const int A = 26;
vector<pair<int, char>> adj[N];
vector<vector<int>> child(N, vector<int>(A));
int parent[N];
vector<int> nodes_in_level[N];
int size[N];
int compress[N];
int decompress[N];
int n;
void Build(int node, int par, int height = 0) {
  size[node] = 1;
  parent[node] = par;
  nodes_in_level[height].push_back(node);
  for (auto v : adj[node]) {
    if (v.first == par) continue;
    Build(v.first, node, height + 1);
    size[node] += size[v.first];
    child[node][v.second - 'a'] = v.first;
  }
}
void Compress(int node, int& id) {
  decompress[id] = node;
  compress[node] = id;
  for (int i = 0; i < A; ++i) {
    if (child[node][i] == 0) continue;
    Compress(child[node][i], ++id);
  }
}
void Compress(const vector<int>& nodes, int& id) {
  for (int node : nodes) {
    Compress(node, ++id);
  }
}
void Merge(int node1, int node2, vector<vector<int>>& child) {
  for (int i = 0; i < A; ++i) {
    if (child[node1][i] == 0) {
      child[node1][i] = child[node2][i];
      continue;
    }
    if (child[node2][i] == 0) {
      continue;
    }
    Merge(child[node1][i], child[node2][i], child);
  }
}
vector<vector<int>> Merge(const vector<int>& nodes) {
  int n = 0;
  Compress(nodes, n);
  vector<vector<int>> child(n + 1, vector<int>(A));
  for (int i = 1; i <= n; ++i) {
    child[i] = ::child[decompress[i]];
    for (int& v : child[i]) {
      if (v == 0) continue;
      v = compress[v];
    }
  }
  int root = 1;
  for (int node : nodes) {
    Merge(root, compress[node], child);
  }
  return child;
}
int CountUnionSize(int node1, int node2, const vector<vector<int>>& child1,
                   const vector<vector<int>>& child2) {
  int res = 1;
  for (int i = 0; i < A; ++i) {
    if (child2[node2][i] == 0) {
      res += size[child1[node1][i]];
      continue;
    }
    res += CountUnionSize(child1[node1][i], child2[node2][i], child1, child2);
  }
  return res;
}
void Print(const vector<vector<int>>& child, int root) {
  for (int i = 0; i < A; ++i) {
    if (child[root][i] == 0) continue;
    cout << root << ' ' << char(i + 'a') << ' ' << child[root][i] << endl;
    Print(child, child[root][i]);
  }
}
int GetUnionSize(const vector<int>& nodes) {
  if (nodes.empty()) return 0;
  if (nodes.size() == 1) return size[nodes.back()];
  int biggest = nodes.back();
  for (int node : nodes) {
    if (size[biggest] < size[node]) {
      biggest = node;
    }
  }
  vector<int> other_nodes;
  for (int node : nodes) {
    if (node != biggest) {
      other_nodes.push_back(node);
    }
  }
  auto other_nodes_child = Merge(other_nodes);
  return CountUnionSize(biggest, 1, child, other_nodes_child);
}
int Solve(int level) {
  int last_parent = -1;
  vector<int> curr_nodes;
  int res = n;
  for (int node : nodes_in_level[level]) {
    if (parent[node] != last_parent) {
      res += max(0, GetUnionSize(curr_nodes) - 1);
      curr_nodes.clear();
      last_parent = parent[node];
    }
    curr_nodes.push_back(node);
    res -= size[node];
  }
  res += max(0, GetUnionSize(curr_nodes) - 1);
  return res;
}
pair<int, int> Solve() {
  int res = n;
  int level = 1;
  for (int i = 1; i < N; ++i) {
    int tmp = Solve(i);
    if (tmp < res) {
      res = tmp;
      level = i;
    }
  }
  return {res, level};
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n;
  for (int i = 1; i < n; ++i) {
    char c;
    int u, v;
    cin >> u >> v >> c;
    adj[u].emplace_back(v, c);
    adj[v].emplace_back(u, c);
  }
  Build(1, -1);
  auto res = Solve();
  cout << res.first << '\n' << res.second << '\n';
}
