← Home
```go
package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

type FastScanner struct {
	data []byte
	idx  int
}

func (fs *FastScanner) nextInt() int {
	for fs.idx < len(fs.data) && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	n := 0
	for fs.idx < len(fs.data) && fs.data[fs.idx] > ' ' {
		n = n*10 + int(fs.data[fs.idx]-'0')
		fs.idx++
	}
	return n
}

func (fs *FastScanner) nextByte() byte {
	for fs.idx < len(fs.data) && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	b := fs.data[fs.idx]
	fs.idx++
	return b
}

type pair struct {
	a, b  int32
	stage byte
}

var typeChildren [][26]int32
var typeNext []int32
var typeSize []int32
var typeHead map[uint64]int32

var unionMemo map[uint64]int32
var unionStack []pair

var leafID int32

func hashArr(a [26]int32) uint64 {
	h := uint64(1469598103934665603)
	for i := 0; i < 26; i++ {
		h ^= uint64(uint32(a[i])) + uint64(i+1)*0x9e3779b97f4a7c15
		h *= 1099511628211
	}
	return h
}

func getType(a [26]int32) int32 {
	h := hashArr(a)
	for id := typeHead[h]; id != 0; id = typeNext[int(id)] {
		if typeChildren[int(id)] == a {
			return id
		}
	}
	id := int32(len(typeChildren))
	typeChildren = append(typeChildren, a)
	typeNext = append(typeNext, typeHead[h])
	typeHead[h] = id
	var s int32 = 1
	for i := 0; i < 26; i++ {
		s += typeSize[int(a[i])]
	}
	typeSize = append(typeSize, s)
	return id
}

func pairKey(a, b int32) uint64 {
	return uint64(uint32(a))<<32 | uint64(uint32(b))
}

func unionTypes(a, b int32) int32 {
	if a == 0 {
		return b
	}
	if b == 0 {
		return a
	}
	if a == b {
		return a
	}
	if a == leafID {
		return b
	}
	if b == leafID {
		return a
	}
	if a > b {
		a, b = b, a
	}
	k0 := pairKey(a, b)
	if v, ok := unionMemo[k0]; ok && v > 0 {
		return v
	}

	unionStack = unionStack[:0]
	if _, ok := unionMemo[k0]; !ok {
		unionMemo[k0] = -1
		unionStack = append(unionStack, pair{a: a, b: b, stage: 0})
	}

	for len(unionStack) > 0 {
		s := unionStack[len(unionStack)-1]
		unionStack = unionStack[:len(unionStack)-1]

		if s.stage == 0 {
			unionStack = append(unionStack, pair{a: s.a, b: s.b, stage: 1})
			ca := typeChildren[int(s.a)]
			cb := typeChildren[int(s.b)]
			for i := 0; i < 26; i++ {
				x := ca[i]
				y := cb[i]
				if x == 0 || y == 0 || x == y || x == leafID || y == leafID {
					continue
				}
				if x > y {
					x, y = y, x
				}
				k := pairKey(x, y)
				if _, ok := unionMemo[k]; !ok {
					unionMemo[k] = -1
					unionStack = append(unionStack, pair{a: x, b: y, stage: 0})
				}
			}
		} else {
			var arr [26]int32
			ca := typeChildren[int(s.a)]
			cb := typeChildren[int(s.b)]
			for i := 0; i < 26; i++ {
				x := ca[i]
				y := cb[i]
				if x == 0 {
					arr[i] = y
				} else if y == 0 || x == y {
					arr[i] = x
				} else if x == leafID {
					arr[i] = y
				} else if y == leafID {
					arr[i] = x
				} else {
					if x > y {
						x, y = y, x
					}
					arr[i] = unionMemo[pairKey(x, y)]
				}
			}
			unionMemo[pairKey(s.a, s.b)] = getType(arr)
		}
	}

	return unionMemo[k0]
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	fs := FastScanner{data: data}

	n := fs.nextInt()

	head := make([]int, n+1)
	to := make([]int, n)
	next := make([]int, n)
	lab := make([]byte, n)

	ec := 0
	for i := 1; i < n; i++ {
		u := fs.nextInt()
		v := fs.nextInt()
		x := fs.nextByte()
		ec++
		to[ec] = v
		next[ec] = head[u]
		head[u] = ec
		lab[ec] = x - 'a'
	}

	depth := make([]int, n+1)
	levelCnt := make([]int, n+1)
	order := make([]int, 0, n)
	stack := make([]int, 0, n)
	stack = append(stack, 1)
	levelCnt[0] = 1
	maxDepth := 0

	for len(stack) > 0 {
		v := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		order = append(order, v)
		for e := head[v]; e != 0; e = next[e] {
			w := to[e]
			depth[w] = depth[v] + 1
			d := depth[w]
			levelCnt[d]++
			if d > maxDepth {
				maxDepth = d
			}
			stack = append(stack, w)
		}
	}

	typeChildren = make([][26]int32, 1, n+1)
	typeNext = make([]int32, 1, n+1)
	typeSize = make([]int32, 1, n+1)
	typeHead = make(map[uint64]int32, n*2+1)

	var zero [26]int32
	leafID = getType(zero)

	nodeType := make([]int32, n+1)

	for i := len(order) - 1; i >= 0; i-- {
		v := order[i]
		var arr [26]int32
		for e := head[v]; e != 0; e = next[e] {
			arr[int(lab[e])] = nodeType[to[e]]
		}
		nodeType[v] = getType(arr)
	}

	ordTypeCount := len(typeChildren) - 1
	unionMemo = make(map[uint64]int32, ordTypeCount*2+1)
	unionStack = make([]pair, 0, 64)

	gType := make([]int32, ordTypeCount+1)
	for id := 1; id <= ordTypeCount; id++ {
		res := leafID
		ch := typeChildren[id]
		for i := 0; i < 26; i++ {
			if ch[i] != 0 {
				res = unionTypes(res, ch[i])
			}
		}
		gType[id] = typeSize[int(res)] - 1
	}

	sumG := make([]int, maxDepth+1)
	for v := 1; v <= n; v++ {
		sumG[depth[v]] += int(gType[int(nodeType[v])])
	}

	bestSize := n + 1
	bestP := 1
	prefix := 0
	for d := 0; d < maxDepth; d++ {
		prefix += levelCnt[d]
		cur := prefix + sumG[d]
		if cur < bestSize {
			bestSize = cur
			bestP = d + 1
		}
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	fmt.Fprintln(out, bestSize)
	fmt.Fprintln(out, bestP)
	out.Flush()
}
```