← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

type Pair struct {
	cnt int
	sum int
}

func better(a, b Pair) bool {
	if a.cnt != b.cnt {
		return a.cnt > b.cnt
	}
	return a.sum < b.sum
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		val := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			val = val*10 + int(data[idx]-'0')
			idx++
		}
		return val
	}

	n := nextInt()
	adj := make([][]int, n+1)
	for i := 0; i < n-1; i++ {
		u := nextInt()
		v := nextInt()
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	deg := make([]int, n+1)
	for i := 1; i <= n; i++ {
		deg[i] = len(adj[i])
	}

	parent := make([]int, n+1)
	order := make([]int, 0, n)
	stack := make([]int, 0, n)
	stack = append(stack, 1)
	parent[1] = -1

	for len(stack) > 0 {
		v := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		order = append(order, v)
		for _, to := range adj[v] {
			if to == parent[v] {
				continue
			}
			parent[to] = v
			stack = append(stack, to)
		}
	}

	dp0 := make([]Pair, n+1)
	dp1 := make([]Pair, n+1)

	for i := n - 1; i >= 0; i-- {
		v := order[i]
		p1 := Pair{cnt: 1, sum: deg[v]}
		p0 := Pair{}
		for _, to := range adj[v] {
			if to == parent[v] {
				continue
			}
			p1.cnt += dp0[to].cnt
			p1.sum += dp0[to].sum
			if better(dp1[to], dp0[to]) {
				p0.cnt += dp1[to].cnt
				p0.sum += dp1[to].sum
			} else {
				p0.cnt += dp0[to].cnt
				p0.sum += dp0[to].sum
			}
		}
		dp0[v] = p0
		dp1[v] = p1
	}

	rootTake := 0
	if better(dp1[1], dp0[1]) {
		rootTake = 1
	}

	selected := make([]bool, n+1)
	type State struct {
		v    int
		take int
	}
	st := make([]State, 0, n)
	st = append(st, State{1, rootTake})

	for len(st) > 0 {
		cur := st[len(st)-1]
		st = st[:len(st)-1]
		v := cur.v
		if cur.take == 1 {
			selected[v] = true
			for _, to := range adj[v] {
				if to == parent[v] {
					continue
				}
				st = append(st, State{to, 0})
			}
		} else {
			for _, to := range adj[v] {
				if to == parent[v] {
					continue
				}
				take := 0
				if better(dp1[to], dp0[to]) {
					take = 1
				}
				st = append(st, State{to, take})
			}
		}
	}

	weights := make([]int, n+1)
	for i := 1; i <= n; i++ {
		if selected[i] {
			weights[i] = deg[i]
		} else {
			weights[i] = 1
		}
	}

	actualGood := 0
	var total int64
	for v := 1; v <= n; v++ {
		total += int64(weights[v])
		var s int64
		for _, to := range adj[v] {
			s += int64(weights[to])
		}
		if int64(weights[v]) == s {
			actualGood++
		}
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	out.WriteString(strconv.Itoa(actualGood))
	out.WriteByte(' ')
	out.WriteString(strconv.FormatInt(total, 10))
	out.WriteByte('\n')
	for i := 1; i <= n; i++ {
		if i > 1 {
			out.WriteByte(' ')
		}
		out.WriteString(strconv.Itoa(weights[i]))
	}
	out.WriteByte('\n')
	out.Flush()
}