You are given a forest — an undirected graph with $$$n$$$ vertices such that each its connected component is a tree.The diameter (aka "longest shortest path") of a connected undirected graph is the maximum number of edges in the shortest path between any pair of its vertices.You task is to add some edges (possibly zero) to the graph so that it becomes a tree and the diameter of the tree is minimal possible.If there are multiple correct answers, print any of them.

The first line contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 1000$$$, $$$0 \le m \le n - 1$$$) — the number of vertices of the graph and the number of edges, respectively. Each of the next $$$m$$$ lines contains two integers $$$v$$$ and $$$u$$$ ($$$1 \le v, u \le n$$$, $$$v \ne u$$$) — the descriptions of the edges. It is guaranteed that the given graph is a forest.

In the first line print the diameter of the resulting tree. Each of the next $$$(n - 1) - m$$$ lines should contain two integers $$$v$$$ and $$$u$$$ ($$$1 \le v, u \le n$$$, $$$v \ne u$$$) — the descriptions of the added edges. The resulting graph should be a tree and its diameter should be minimal possible. For $$$m = n - 1$$$ no edges are added, thus the output consists of a single integer — diameter of the given tree. If there are multiple correct answers, print any of them.

NoteIn the first example adding edges (1, 4) or (3, 4) will lead to a total diameter of 3. Adding edge (2, 4), however, will make it 2.Edge (1, 2) is the only option you have for the second example. The diameter is 1.You can't add any edges in the third example. The diameter is already 2.

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.one)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	pre := make([]int, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				pre[next] = s[deep-1][j]
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	mid := s[deep-1][0]
	for i := 0;i < deep/2;i++{
		mid = pre[mid]
	}
	res := &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   mid,
	}
	return res
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			//mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	//if n == 100 && m == 90 {
	//	fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	//}
	sort.Sort(points)
	mp.one = points[0]
	plen := len(points)
	if plen > 1{
		mp.two = points[1]
	}
	if plen > 2{
		mp.three = points[2]
	}
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < plen; i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"time"
)

type tree struct {
	root, height, dia int
}

var n, m, x, y int
var adj map[int][]int
var seen []bool
var rank, parent, comp, maxRank []int

// Ranking ... rank the tree
func Ranking(u, r, c int) int {
	if seen[u] {
		return 0
	}
	var res = u
	seen[u] = true
	rank[u] = r
	comp[u] = c
	for _, v := range adj[u] {
		if !seen[v] {
			parent[v] = u
			var mostRank = Ranking(v, r+1, c)
			if rank[mostRank] > rank[res] {
				res = mostRank
			}
		}
	}
	return res
}

func main() {
	start := time.Now()
	defer func() {
		run := time.Since(start)
		_ = run
		// fmt.Println("Run in", run)
	}()

	var stdin *bufio.Reader
	// LOCAL
	f, _ := os.Open("input.txt")
	stdin = bufio.NewReader(f)

	// ONLINE JUDGE
	stdin = bufio.NewReader(os.Stdin)

	fmt.Fscan(stdin, &n, &m)
	adj = map[int][]int{}
	seen = make([]bool, n)
	rank = make([]int, n)
	parent = make([]int, n)
	comp = make([]int, n)
	maxRank = []int{}

	for i := 0; i < m; i++ {
		fmt.Fscan(stdin, &x, &y)
		x--
		y--
		adj[x] = append(adj[x], y)
		adj[y] = append(adj[y], x)
	}

	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			maxRank = append(maxRank, 0)
			maxRank[c-1] = Ranking(i, 1, c)
		}
	}

	seen = make([]bool, n)
	parent = make([]int, n)
	rank = make([]int, n)
	var forest = make([]tree, len(maxRank))
	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			parent[maxRank[c-1]] = -1
			var longest = Ranking(maxRank[c-1], 0, c)
			forest[c-1].dia = rank[longest]
			forest[c-1].height = rank[longest]/2 + (rank[longest] % 2)
			// Trace
			for h := 0; longest != -1; h++ {
				if rank[longest] == forest[c-1].height {
					forest[c-1].root = longest
				}
				longest = parent[longest]
			}
		}
	}

	sort.Slice(forest[:], func(i, j int) bool {
		return forest[i].height > forest[j].height
	})

	var lastTree = forest[0]
	var dy = []int{}
	for i := 1; i < len(forest); i++ {
		if lastTree.height+forest[i].height+1 > lastTree.dia {
			lastTree.dia = lastTree.height + forest[i].height + 1
		}
		if lastTree.height == forest[i].height {
			lastTree.height++
		}
		dy = append(dy, forest[i].root)
	}

	// fmt.Println("Seen", seen)
	// fmt.Println("Rank", rank)
	// fmt.Println("Parent", parent)
	// fmt.Println("Component", comp)
	// fmt.Println("Max Rank", maxRank)
	// fmt.Println("Forest", forest)
	// fmt.Println(lastTree, dy)
	fmt.Println(lastTree.dia)
	for _, v := range dy {
		fmt.Println(lastTree.root+1, v+1)
	}
}

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1092E(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var n, m, v, w, u, o, mx, maxO int
	Fscan(in, &n, &m)
	g := make([][]int, n+1)
	for ; m > 0; m-- {
		Fscan(in, &v, &w)
		g[v] = append(g[v], w)
		g[w] = append(g[w], v)
	}

	vis := make([]bool, n+1)
	var f func(v, fa, d int)
	f = func(v, fa, d int) {
		vis[v] = true
		if d > mx {
			mx, u = d, v
		}
		for _, w := range g[v] {
			if w != fa {
				f(w, v, d+1)
			}
		}
	}
	var f2 func(v, fa, d int) bool
	f2 = func(v, fa, d int) bool {
		if v == u {
			if d == mx/2 {
				o = v
			}
			return true
		}
		for _, w := range g[v] {
			if w != fa && f2(w, v, d+1) {
				if d == mx/2 {
					o = v
				}
				return true
			}
		}
		return false
	}
	os := []int{}
	maxD := -1
	for i := 1; i <= n; i++ {
		if !vis[i] {
			mx = -1
			f(i, 0, 0)
			mx = -1
			x := u
			f(x, 0, 0)
			o = 0
			f2(x, 0, 0)
			os = append(os, o)
			if mx > maxD {
				maxD = mx
				maxO = o
			}
		}
	}
	for _, o := range os {
		if o != maxO {
			g[maxO] = append(g[maxO], o)
			g[o] = append(g[o], maxO)
		}
	}
	mx = -1
	f(1, 0, 0)
	mx = -1
	f(u, 0, 0)
	Fprintln(out, mx)
	for _, o := range os {
		if o != maxO {
			Fprintln(out, maxO, o)
		}
	}
}

func main() { CF1092E(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.one)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	if n == 100 && m == 90 {
		fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.one)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			//mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	//if n == 100 && m == 90 {
	//	fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	//}
	sort.Sort(points)
	mp.one = points[0]
	plen := len(points)
	if plen > 1{
		mp.two = points[1]
	}
	if plen > 2{
		mp.three = points[2]
	}
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < plen; i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	if n == 100 && m == 90 {
		fmt.Printf("mp=%v\n", mp)
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p
		return
	} else if mp.two == nil {
		mp.two = p
		return
	} else if mp.three == nil {
		mp.three = p
		return
	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool,n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true{
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[(deep-1)/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
		//	fmt.Printf("p=%v\n",p)
		}
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}
/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p
		return
	} else if mp.two == nil {
		mp.two = p
		return
	} else if mp.three == nil {
		mp.three = p
		return
	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			if n == 100 && m == 90 {
				fmt.Printf("p=%v\n", p)
			}
		}
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p
		return
	} else if mp.two == nil {
		mp.two = p
		return
	} else if mp.three == nil {
		mp.three = p
		return
	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool,n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true{
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
		}
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	if n == 100 && m == 90 {
		fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.one)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			//mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	if n == 100 && m == 90 {
		fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	}
	sort.Sort(points)
	mp.one = points[0]
	plen := len(points)
	if plen > 1{
		mp.two = points[1]
	}
	if plen > 2{
		mp.three = points[2]
	}
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < plen; i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.one)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}
	//if n == 100 && m == 90 {
	//	fmt.Printf("mp=%v %v %v\n", mp.one,mp.two,mp.three)
	//}
	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Graph struct {
	header [][]int
}
type point struct {
	index   int
	d       int
	longest int
}
type PointSlice []*point
type maxTp struct {
	one   *point
	two   *point
	three *point
}

func (p *point) getR() int {
	return (p.d + 1) / 2
}
func (p PointSlice) Len() int {
	return len(p)
}
func (p PointSlice) Less(i, j int) bool {
	return p[i].d > p[j].d
}
func (p PointSlice) Swap(i, j int) {
	tmp := p[i]
	p[i] = p[j]
	p[j] = tmp
}
func (mp *maxTp) AddPoint(p *point) {
	if mp.one == nil {
		mp.one = p

	} else if mp.two == nil {
		mp.two = p

	} else if mp.three == nil {
		mp.three = p

	} else if mp.three.d < p.d {
		mp.three = p
	}
	mp.order()
}
func (mp *maxTp) order() {
	if mp.three != nil && mp.three.d > mp.two.d {
		mp.swap(mp.two, mp.three)
	}
	if mp.two != nil && mp.one.d < mp.two.d {
		mp.swap(mp.two, mp.three)
	}
}
func (mp *maxTp) swap(a, b *point) {
	var tmp *point = a
	a = b
	b = tmp
}

func newGraph(size int) *Graph {
	return &Graph{
		header: make([][]int, size),
	}
}
func (g *Graph) addEdge(from, to int) {
	if 0 == len(g.header[from]) {
		g.header[from] = make([]int, 0)
	}
	g.header[from] = append(g.header[from], to)
}

func diameter(g *Graph, root, n int, visited []bool) *point {
	//	fmt.Printf("root=%d \n", root)
	s := make([][]int, n+1)
	s[0] = make([]int, 1)
	s[0][0] = root
	visited[root] = true
	flag := make([]bool, n+1)
	deep := 1
	flag[root] = true
	for {
		nextP := make([]int, 0)
		for j := 0; j < len(s[deep-1]); j++ {
			for _, next := range g.header[s[deep-1][j]] {
				visited[next] = true
				if flag[next] == true {
					continue
				}
				flag[next] = true
				nextP = append(nextP, next)
			}
		}
		if len(nextP) == 0 {
			break
		}
		s[deep] = nextP
		deep++
	}
	//	fmt.Printf("s=%v\n",s)
	return &point{
		d:       deep - 1,
		longest: s[deep-1][0],
		index:   s[deep/2][0],
	}
}
func solveMaxd(mp *maxTp) int {
	var ans int = mp.one.d
	if mp.three == nil && mp.two == nil {
		return ans
	}
	if mp.three == nil {
		if mp.one.d < mp.one.getR()+mp.two.getR()+1 {
			return mp.one.getR() + mp.two.getR() + 1
		} else {
			return mp.one.d
		}
	}
	if mp.two.getR()+mp.three.getR()+2 > ans {
		ans = mp.two.getR() + mp.three.getR() + 2
	}
	if mp.one.getR()+mp.two.getR()+1 > ans {
		ans = mp.one.getR() + mp.two.getR() + 1
	}
	return ans
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	g := newGraph(n + 1)
	for i := 0; i < m; i++ {
		var from, to int
		fmt.Fscanf(buf, "%d %d\n", &from, &to)
		g.addEdge(from, to)
		g.addEdge(to, from)
	}
	visited := make([]bool, n+1)
	points := PointSlice(make([]*point, 0))
	mp := &maxTp{
	}
	for i := 1; i <= n; i++ {
		if visited[i] == false {
			end := diameter(g, i, n, visited)
			p := diameter(g, end.longest, n, visited)
			points = append(points, p)
			mp.AddPoint(p)
			//if n == 100 && m == 90 {
			//	fmt.Printf("p=%v\n", p)
			//}
		}
	}

	sort.Sort(points)
	fmt.Printf("%d\n", solveMaxd(mp))
	for i := 1; i < len(points); i++ {
		fmt.Printf("%d %d\n", points[0].index, points[i].index)
	}
}

/**
12 10
1 2
1 3
1 4
2 5
2 6
2 7
3 8
5 9
5 10
7 11

 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"time"
)

type tree struct {
	root, height, dia int
}

var n, m, x, y int
var adj map[int][]int
var seen []bool
var rank, parent, comp, maxRank []int

// Ranking ... rank the tree
func Ranking(u, r, c int) int {
	if seen[u] {
		return 0
	}
	var res = u
	seen[u] = true
	rank[u] = r
	comp[u] = c
	for _, v := range adj[u] {
		if !seen[v] {
			parent[v] = u
			var mostRank = Ranking(v, r+1, c)
			if rank[mostRank] > rank[res] {
				res = mostRank
			}
		}
	}
	return res
}

func main() {
	start := time.Now()
	defer func() {
		run := time.Since(start)
		_ = run
		// fmt.Println("Run in", run)
	}()

	var stdin *bufio.Reader
	// LOCAL
	f, _ := os.Open("input.txt")
	stdin = bufio.NewReader(f)

	// ONLINE JUDGE
	stdin = bufio.NewReader(os.Stdin)

	fmt.Fscan(stdin, &n, &m)
	adj = map[int][]int{}
	seen = make([]bool, n)
	rank = make([]int, n)
	parent = make([]int, n)
	comp = make([]int, n)
	maxRank = []int{}

	for i := 0; i < m; i++ {
		fmt.Fscan(stdin, &x, &y)
		x--
		y--
		adj[x] = append(adj[x], y)
		adj[y] = append(adj[y], x)
	}

	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			maxRank = append(maxRank, 0)
			maxRank[c-1] = Ranking(i, 1, c)
		}
	}

	seen = make([]bool, n)
	parent = make([]int, n)
	rank = make([]int, n)
	var forest = make([]tree, len(maxRank))
	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			parent[maxRank[c-1]] = -1
			var longest = Ranking(maxRank[c-1], 1, c)
			forest[c-1].dia = rank[longest] - 1
			var rootRank = rank[longest]/2 + 1
			// Trace
			for h := 0; longest != -1; h++ {
				if rank[longest] == rootRank {
					forest[c-1].root = longest
				}
				if parent[longest] == -1 {
					forest[c-1].height = h
				}
				longest = parent[longest]
			}
		}
	}

	sort.Slice(forest[:], func(i, j int) bool {
		return forest[i].height > forest[j].height
	})

	var lastTree = forest[0]
	var dx, dy = []int{}, []int{}
	for i := 1; i < len(forest); i++ {
		if lastTree.height == forest[i].height {
			lastTree.height++
		}
		lastTree.dia = lastTree.height + forest[i].height
		dx = append(dx, lastTree.root)
		dy = append(dy, forest[i].root)
	}

	// fmt.Println("Seen", seen)
	// fmt.Println("Rank", rank)
	// fmt.Println("Parent", parent)
	// fmt.Println("Component", comp)
	// fmt.Println("Max Rank", maxRank)
	// fmt.Println("Forest", forest)
	// fmt.Println(lastTree, dy)
	fmt.Println(lastTree.dia)
	for _, v := range dy {
		fmt.Println(lastTree.root+1, v+1)
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"time"
)

type tree struct {
	root, height, dia int
}

var n, m, x, y int
var adj map[int][]int
var seen []bool
var rank, parent, comp, maxRank []int

// Ranking ... rank the tree
func Ranking(u, r, c int) int {
	if seen[u] {
		return 0
	}
	var res = u
	seen[u] = true
	rank[u] = r
	comp[u] = c
	for _, v := range adj[u] {
		if !seen[v] {
			parent[v] = u
			var mostRank = Ranking(v, r+1, c)
			if rank[mostRank] > rank[res] {
				res = mostRank
			}
		}
	}
	return res
}

func main() {
	start := time.Now()
	defer func() {
		run := time.Since(start)
		_ = run
		// fmt.Println("Run in", run)
	}()

	var stdin *bufio.Reader
	// LOCAL
	f, _ := os.Open("input.txt")
	stdin = bufio.NewReader(f)

	// ONLINE JUDGE
	stdin = bufio.NewReader(os.Stdin)

	fmt.Fscan(stdin, &n, &m)
	adj = map[int][]int{}
	seen = make([]bool, n)
	rank = make([]int, n)
	parent = make([]int, n)
	comp = make([]int, n)
	maxRank = []int{}

	for i := 0; i < m; i++ {
		fmt.Fscan(stdin, &x, &y)
		x--
		y--
		adj[x] = append(adj[x], y)
		adj[y] = append(adj[y], x)
	}

	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			maxRank = append(maxRank, 0)
			maxRank[c-1] = Ranking(i, 1, c)
		}
	}

	seen = make([]bool, n)
	parent = make([]int, n)
	rank = make([]int, n)
	var forest = make([]tree, len(maxRank))
	for i, c := 0, 0; i < n; i++ {
		if !seen[i] {
			c++
			parent[maxRank[c-1]] = -1
			var longest = Ranking(maxRank[c-1], 0, c)
			forest[c-1].dia = rank[longest]
			forest[c-1].height = rank[longest]/2 + (rank[longest] % 2)
			// Trace
			for h := 0; longest != -1; h++ {
				if rank[longest] == forest[c-1].height {
					forest[c-1].root = longest
				}
				longest = parent[longest]
			}
		}
	}

	sort.Slice(forest[:], func(i, j int) bool {
		return forest[i].height > forest[j].height
	})

	var lastTree = forest[0]
	var dy = []int{}
	for i := 1; i < len(forest); i++ {
		lastTree.dia = lastTree.height + forest[i].height + 1
		if lastTree.height == forest[i].height {
			lastTree.height++
		}
		dy = append(dy, forest[i].root)
	}

	// fmt.Println("Seen", seen)
	// fmt.Println("Rank", rank)
	// fmt.Println("Parent", parent)
	// fmt.Println("Component", comp)
	// fmt.Println("Max Rank", maxRank)
	// fmt.Println("Forest", forest)
	// fmt.Println(lastTree, dy)
	fmt.Println(lastTree.dia)
	for _, v := range dy {
		fmt.Println(lastTree.root+1, v+1)
	}
}

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1092E(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var n, m, v, w, u, mx, maxO int
	Fscan(in, &n, &m)
	g := make([][]int, n+1)
	for ; m > 0; m-- {
		Fscan(in, &v, &w)
		g[v] = append(g[v], w)
		g[w] = append(g[w], v)
	}

	vis := make([]bool, n+1)
	var vs []int
	dep := make([]int, n+1)
	var f func(v, fa, d int)
	f = func(v, fa, d int) {
		vis[v] = true
		vs = append(vs, v)
		dep[v] = d
		if d > mx {
			mx, u = d, v
		}
		for _, w := range g[v] {
			if w != fa {
				f(w, v, d+1)
			}
		}
	}
	os := []int{}
	maxD := -1
	for i := 1; i <= n; i++ {
		if !vis[i] {
			mx = -1
			f(i, 0, 0)
			vs = []int{}
			mx = -1
			f(u, 0, 0)
			for _, v := range vs {
				if dep[v] == mx/2 {
					os = append(os, v)
					if mx > maxD {
						maxD = mx
						maxO = v
					}
					break
				}
			}
		}
	}
	for _, o := range os {
		if o != maxO {
			g[maxO] = append(g[maxO], o)
			g[o] = append(g[o], maxO)
		}
	}
	mx = -1
	f(1, 0, 0)
	mx = -1
	f(u, 0, 0)
	Fprintln(out, mx)
	for _, o := range os {
		if o != maxO {
			Fprintln(out, maxO, o)
		}
	}
}

func main() { CF1092E(os.Stdin, os.Stdout) }


There are n cities and n - 1 roads in the Seven Kingdoms, each road connects two cities and we can reach any city from any other by the roads.Theon and Yara Greyjoy are on a horse in the first city, they are starting traveling through the roads. But the weather is foggy, so they can’t see where the horse brings them. When the horse reaches a city (including the first one), it goes to one of the cities connected to the current city. But it is a strange horse, it only goes to cities in which they weren't before. In each such city, the horse goes with equal probabilities and it stops when there are no such cities. Let the length of each road be 1. The journey starts in the city 1. What is the expected length (expected value of length) of their journey? You can read about expected (average) value by the link https://en.wikipedia.org/wiki/Expected_value.

The first line contains a single integer n (1 ≤ n ≤ 100000) — number of cities. Then n - 1 lines follow. The i-th line of these lines contains two integers ui and vi (1 ≤ ui, vi ≤ n, ui ≠ vi) — the cities connected by the i-th road. It is guaranteed that one can reach any city from any other by the roads.

Print a number — the expected length of their journey. The journey starts in the city 1. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6. Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

NoteIn the first sample, their journey may end in cities 3 or 4 with equal probability. The distance to city 3 is 1 and to city 4 is 2, so the expected length is 1.5.In the second sample, their journey may end in city 4 or 5. The distance to the both cities is 2, so the expected length is 2.

package main

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

func main() {
	in := NewScanner(os.Stdin)
	nV := in.NextInt()

	T := make([][]int, nV)
	for i := 0; i < nV-1; i++ {
		u, v := in.NextInt()-1, in.NextInt()-1
		T[u] = append(T[u], v)
		T[v] = append(T[v], u)
	}

	sums := make([]float64, nV)
	dfs(T, sums, 0, -1)
	fmt.Printf("%f\n", sums[0])
}

func dfs(T [][]int, sums []float64, current, parent int) {
	sum := 0
	for _, child := range T[current] {
		if child == parent {
			continue
		}
		dfs(T, sums, child, current)
		sum += 1
		sums[current] += sums[child] + 1
	}
	if sum > 0 {
		sums[current] /= float64(sum)
	}
}

//Boiler-Plate
func assert(x bool) {
	if !x {
		panic("assertion failed")
	}
}

type Scanner struct {
	is     io.Reader
	buffer [1 << 16]byte
	size   int
	pos    int
}

func NewScanner(in io.Reader) *Scanner {
	return &Scanner{is: in}
}

func (s *Scanner) nextChar() int {
	if s.pos >= s.size {
		var err error
		s.size, err = s.is.Read(s.buffer[:])
		s.pos = 0
		if err == io.EOF {
			return -1
		}
	}
	assert(s.pos < s.size)
	c := s.buffer[s.pos]
	s.pos++
	return int(c)
}

const BitsPerInt = 32 << uint(^uint(0)>>63)

const MinInt = -1 << (BitsPerInt - 1)

const MaxInt = -(MinInt + 1)

func (s *Scanner) NextInt() int {
	c := s.nextChar()
	for c == ' ' || c == '\r' || c == '\n' || c == '\t' {
		c = s.nextChar()
	}
	if c == '-' {
		c = s.nextChar()
		assert('0' <= c && c <= '9')
		n := -(c - '0')
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n > MinInt/10 || n == MinInt/10 && d <= -(MinInt%10))
			n = n*10 - d
		}
		return n
	} else {
		assert('0' <= c && c <= '9')
		n := c - '0'
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n < MaxInt/10 || n == MaxInt/10 && d <= MaxInt%10)
			n = n*10 + d
		}
		return n
	}
}

package main

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

func main() {
	in := NewScanner(os.Stdin)
	nV := in.NextInt()

	T := make([][]int, nV)
	for i := 0; i < nV-1; i++ {
		u, v := in.NextInt()-1, in.NextInt()-1
		T[u] = append(T[u], v)
		T[v] = append(T[v], u)
	}

	sums := make([]float64, nV)
	dfs(T, sums, 0, -1)
	fmt.Printf("%f\n", sums[0])
}

func dfs(T [][]int, sums []float64, current, parent int) {
	sum := 0
	for _, child := range T[current] {
		if child == parent {
			continue
		}
		dfs(T, sums, child, current)
		sum += 1
		sums[current] += sums[child] + 1
	}
	if sum > 0 {
		sums[current] /= float64(sum)
	} else {
		sums[current] = 0
	}
}

//Boiler-Plate
func assert(x bool) {
	if !x {
		panic("assertion failed")
	}
}

type Scanner struct {
	is     io.Reader
	buffer [1 << 16]byte
	size   int
	pos    int
}

func NewScanner(in io.Reader) *Scanner {
	return &Scanner{is: in}
}

func (s *Scanner) nextChar() int {
	if s.pos >= s.size {
		var err error
		s.size, err = s.is.Read(s.buffer[:])
		s.pos = 0
		if err == io.EOF {
			return -1
		}
	}
	assert(s.pos < s.size)
	c := s.buffer[s.pos]
	s.pos++
	return int(c)
}

const BitsPerInt = 32 << uint(^uint(0)>>63)

const MinInt = -1 << (BitsPerInt - 1)

const MaxInt = -(MinInt + 1)

func (s *Scanner) NextInt() int {
	c := s.nextChar()
	for c == ' ' || c == '\r' || c == '\n' || c == '\t' {
		c = s.nextChar()
	}
	if c == '-' {
		c = s.nextChar()
		assert('0' <= c && c <= '9')
		n := -(c - '0')
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n > MinInt/10 || n == MinInt/10 && d <= -(MinInt%10))
			n = n*10 - d
		}
		return n
	} else {
		assert('0' <= c && c <= '9')
		n := c - '0'
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n < MaxInt/10 || n == MaxInt/10 && d <= MaxInt%10)
			n = n*10 + d
		}
		return n
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var used []bool

func solve() {
	n := readInt()
	used = make([]bool, n)
	adj := make([][]int, n)
	for i := 1; i < n; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
		adj[v] = append(adj[v], u)
	}

	fmt.Printf("%f", dfs(adj, 0))
}

func dfs(adj [][]int, v int) float64 {
	used[v] = true
	cnt := 0
	var sum float64
	for _, u := range adj[v] {
		if !used[u] {
			cnt++
		}
	}
	if cnt == 0 {
		return 0
	}
	for _, u := range adj[v] {
		if !used[u] {
			sum += dfs(adj, u) + float64(1)
		}
	}
	return sum / float64(cnt)
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

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

// github.com/EndlessCheng/codeforces-go
func CF839C(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var n, v, w int
	Fscan(in, &n)
	g := make([][]int, n)
	g[0] = append(g[0], -1)
	for i := 1; i < n; i++ {
		Fscan(in, &v, &w)
		v--
		w--
		g[v] = append(g[v], w)
		g[w] = append(g[w], v)
	}
	var f func(v, fa int) float64
	f = func(v, fa int) (l float64) {
		if len(g[v]) == 1 {
			return
		}
		p := 1 / float64(len(g[v])-1)
		for _, w := range g[v] {
			if w != fa {
				l += p * (f(w, v) + 1)
			}
		}
		return
	}
	ans := f(0, -1)
	Fprintf(out, "%.15f", ans)
}

func main() { CF839C(os.Stdin, os.Stdout) }

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type tuple struct {
	node         int
	branch_count float64
}

func main() {
	sc := NewScanner()
	N := sc.NextInt()
	edge := make([][]int, N)
	for i := 0; i < N; i++ {
		edge[i] = make([]int, 0)
	}
	for i := 0; i < N-1; i++ {
		a, b := sc.NextInt()-1, sc.NextInt()-1
		edge[a] = append(edge[a], b)
		edge[b] = append(edge[b], a)
	}

	checked := make([]bool, N)
	queue := make([]tuple, 1)
	queue[0] = tuple{0, 1}
	checked[0] = true
	count := 0
	p := 0

	ans := 0.0

	for {
		last := len(queue)
		if p == last {
			break
		}
		for ; p < last; p++ {
			branch_count := len(edge[queue[p].node]) - 1
			if p == 0 {
				branch_count++
			}
			for _, nx := range edge[queue[p].node] {
				if !checked[nx] {
					queue = append(queue, tuple{nx, queue[p].branch_count * float64(branch_count)})
					checked[nx] = true
				}
			}
			if branch_count == 0 {
				ans += float64(count) / float64(queue[p].branch_count)
			}
		}
		count++
	}
	fmt.Println(ans)
}

type Scanner struct {
	r   *bufio.Reader
	buf []byte
	p   int
}

func NewScanner() *Scanner {
	rdr := bufio.NewReaderSize(os.Stdin, 1000)
	return &Scanner{r: rdr}
}
func (s *Scanner) Next() string {
	s.pre()
	start := s.p
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}
	result := string(s.buf[start:s.p])
	s.p++
	return result
}
func (s *Scanner) NextLine() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)
	return string(s.buf[start:])
}
func (s *Scanner) NextInt() int {
	v, _ := strconv.Atoi(s.Next())
	return v
}
func (s *Scanner) NextInt64() int64 {
	v, _ := strconv.ParseInt(s.Next(), 10, 64)
	return v
}

func (s *Scanner) NextIntArray() []int {
	s.pre()
	start := s.p
	result := []int{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 0)
			result = append(result, int(v))
			start = s.p + 1
		}
	}

	return result
}
func (s *Scanner) NextInt64Array() []int64 {
	s.pre()
	start := s.p
	result := []int64{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 64)
			result = append(result, v)
			start = s.p + 1
		}
	}
	return result
}

func (s *Scanner) NextMap() map[int]bool {
	s.pre()
	start := s.p
	mp := map[int]bool{}
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			v, _ := strconv.Atoi(string(s.buf[start:s.p]))
			mp[v] = true
			start = s.p + 1
		}
	}
	v, _ := strconv.Atoi(string(s.buf[start:s.p]))
	mp[v] = true

	return mp
}

func (s *Scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}
func (s *Scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}

package main

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

func main() {
	in := NewScanner(os.Stdin)
	nV := in.NextInt()

	T := make([][]int, nV)
	for i := 0; i < nV-1; i++ {
		u, v := in.NextInt()-1, in.NextInt()-1
		T[u] = append(T[u], v)
		T[v] = append(T[v], u)
	}

	sums := make([]float64, nV)
	dfs(T, sums, 0, -1)
	fmt.Printf("%f\n", sums[0]/2.0)
}

func dfs(T [][]int, sums []float64, current, parent int) {
	for _, child := range T[current] {
		if child == parent {
			continue
		}
		dfs(T, sums, child, current)
		sums[current] += sums[child] + 1
	}
}

//Boiler-Plate
func assert(x bool) {
	if !x {
		panic("assertion failed")
	}
}

type Scanner struct {
	is     io.Reader
	buffer [1 << 16]byte
	size   int
	pos    int
}

func NewScanner(in io.Reader) *Scanner {
	return &Scanner{is: in}
}

func (s *Scanner) nextChar() int {
	if s.pos >= s.size {
		var err error
		s.size, err = s.is.Read(s.buffer[:])
		s.pos = 0
		if err == io.EOF {
			return -1
		}
	}
	assert(s.pos < s.size)
	c := s.buffer[s.pos]
	s.pos++
	return int(c)
}

const BitsPerInt = 32 << uint(^uint(0)>>63)

const MinInt = -1 << (BitsPerInt - 1)

const MaxInt = -(MinInt + 1)

func (s *Scanner) NextInt() int {
	c := s.nextChar()
	for c == ' ' || c == '\r' || c == '\n' || c == '\t' {
		c = s.nextChar()
	}
	if c == '-' {
		c = s.nextChar()
		assert('0' <= c && c <= '9')
		n := -(c - '0')
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n > MinInt/10 || n == MinInt/10 && d <= -(MinInt%10))
			n = n*10 - d
		}
		return n
	} else {
		assert('0' <= c && c <= '9')
		n := c - '0'
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n < MaxInt/10 || n == MaxInt/10 && d <= MaxInt%10)
			n = n*10 + d
		}
		return n
	}
}

package main

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

func main() {
	in := NewScanner(os.Stdin)
	nV := in.NextInt()

	T := make([][]int, nV)
	for i := 0; i < nV-1; i++ {
		u, v := in.NextInt()-1, in.NextInt()-1
		T[u] = append(T[u], v)
		T[v] = append(T[v], u)
	}

	sums := make([]int, nV)
	dfs(T, sums, 0, -1)
	fmt.Printf("%f\n", float64(sums[1]+sums[2])/2.0)
}

func dfs(T [][]int, sums []int, current, parent int) {
	sum := 0
	for _, child := range T[current] {
		if child == parent {
			continue
		}
		dfs(T, sums, child, current)
		sum += 1
	}
	sums[current] = sum + 1
}

//Boiler-Plate
func assert(x bool) {
	if !x {
		panic("assertion failed")
	}
}

type Scanner struct {
	is     io.Reader
	buffer [1 << 16]byte
	size   int
	pos    int
}

func NewScanner(in io.Reader) *Scanner {
	return &Scanner{is: in}
}

func (s *Scanner) nextChar() int {
	if s.pos >= s.size {
		var err error
		s.size, err = s.is.Read(s.buffer[:])
		s.pos = 0
		if err == io.EOF {
			return -1
		}
	}
	assert(s.pos < s.size)
	c := s.buffer[s.pos]
	s.pos++
	return int(c)
}

const BitsPerInt = 32 << uint(^uint(0)>>63)

const MinInt = -1 << (BitsPerInt - 1)

const MaxInt = -(MinInt + 1)

func (s *Scanner) NextInt() int {
	c := s.nextChar()
	for c == ' ' || c == '\r' || c == '\n' || c == '\t' {
		c = s.nextChar()
	}
	if c == '-' {
		c = s.nextChar()
		assert('0' <= c && c <= '9')
		n := -(c - '0')
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n > MinInt/10 || n == MinInt/10 && d <= -(MinInt%10))
			n = n*10 - d
		}
		return n
	} else {
		assert('0' <= c && c <= '9')
		n := c - '0'
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n < MaxInt/10 || n == MaxInt/10 && d <= MaxInt%10)
			n = n*10 + d
		}
		return n
	}
}

package main

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

func main() {
	in := NewScanner(os.Stdin)
	nV := in.NextInt()

	T := make([][]int, nV)
	for i := 0; i < nV-1; i++ {
		u, v := in.NextInt()-1, in.NextInt()-1
		T[u] = append(T[u], v)
		T[v] = append(T[v], u)
	}

	sums := make([]float64, nV)
	dfs(T, sums, 0, -1)
	fmt.Println(sums)
	fmt.Printf("%f\n", sums[0])
}

func dfs(T [][]int, sums []float64, current, parent int) {
	for _, child := range T[current] {
		if child == parent {
			continue
		}
		dfs(T, sums, child, current)
		sums[current] += sums[child] + 1
	}
}

//Boiler-Plate
func assert(x bool) {
	if !x {
		panic("assertion failed")
	}
}

type Scanner struct {
	is     io.Reader
	buffer [1 << 16]byte
	size   int
	pos    int
}

func NewScanner(in io.Reader) *Scanner {
	return &Scanner{is: in}
}

func (s *Scanner) nextChar() int {
	if s.pos >= s.size {
		var err error
		s.size, err = s.is.Read(s.buffer[:])
		s.pos = 0
		if err == io.EOF {
			return -1
		}
	}
	assert(s.pos < s.size)
	c := s.buffer[s.pos]
	s.pos++
	return int(c)
}

const BitsPerInt = 32 << uint(^uint(0)>>63)

const MinInt = -1 << (BitsPerInt - 1)

const MaxInt = -(MinInt + 1)

func (s *Scanner) NextInt() int {
	c := s.nextChar()
	for c == ' ' || c == '\r' || c == '\n' || c == '\t' {
		c = s.nextChar()
	}
	if c == '-' {
		c = s.nextChar()
		assert('0' <= c && c <= '9')
		n := -(c - '0')
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n > MinInt/10 || n == MinInt/10 && d <= -(MinInt%10))
			n = n*10 - d
		}
		return n
	} else {
		assert('0' <= c && c <= '9')
		n := c - '0'
		c = s.nextChar()
		for '0' <= c && c <= '9' {
			d := c - '0'
			c = s.nextChar()
			assert(n < MaxInt/10 || n == MaxInt/10 && d <= MaxInt%10)
			n = n*10 + d
		}
		return n
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var lastSum int
var lastCnt int

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	vis := make(map[int]bool)
	dfs(adj, 0, -1, 0, vis)
	fmt.Printf("%f", float64(lastSum)/float64(lastCnt))
}

func dfs(adj [][]int, cur, from, l int, vis map[int]bool) {
	vis[cur] = true
	last := true
	for _, v := range adj[cur] {
		if v != from && vis[v] == false {
			dfs(adj, v, cur, l+1, vis)
			last = false
		}
	}
	if last {
		lastCnt++
		lastSum += l
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

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

	fmt.Printf("%f", dfs(adj, 0, -1))
}

func dfs(adj [][]int, v, p int) float64 {
	var sum float64
	for _, u := range adj[v] {
		if u != p {
			sum += dfs(adj, u, v) + float64(1)
		}
	}
	cnt := len(adj[v])
	if p != -1 {
		cnt--
	}
	if cnt > 0 {
		sum /= float64(cnt)
	}
	return sum
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var res []int

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	vis := make(map[int]bool)
	dfs(adj, 0, -1, 0, vis)
	total := int64(0)
	for i := 0; i < len(res); i++ {
		total += int64(res[i])
	}
	fmt.Printf("%+v", float64(total)/float64(len(res)))
}

func dfs(adj [][]int, cur, from, l int, vis map[int]bool) {
	vis[cur] = true
	last := true
	for _, v := range adj[cur] {
		if v != from && vis[v] == false {
			dfs(adj, v, cur, l+1, vis)
			last = false
		}
	}
	if last {
		res = append(res, l)
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var lastSum int
var lastCnt int

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	dfs(adj, 0, -1, 0)
	fmt.Printf("%+v", float64(lastSum)/float64(lastCnt))
}

func dfs(adj [][]int, cur, from, l int) {
	last := true
	for _, v := range adj[cur] {
		if v != from {
			dfs(adj, v, cur, l+1)
			last = false
		}
	}
	if last {
		lastCnt++
		lastSum += l
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

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

	fmt.Printf("%f", dfs(adj, 0, -1))
}

func dfs(adj [][]int, cur, from int) float64 {
	cnt := 0
	var sum float64
	for _, v := range adj[cur] {
		if v != from {
			sum += dfs(adj, v, cur) + 1
			cnt++
		}
	}
	if cnt != 0 {
		sum /= float64(cnt)
	}
	return sum
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var lastSum int
var lastCnt int

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	dfs(adj, 0, 0, -1)
	fmt.Printf("%+v", float64(lastSum)/float64(lastCnt))
}

func dfs(adj [][]int, cur, from, l int) {
	last := true
	for _, v := range adj[cur] {
		if v != from {
			dfs(adj, v, cur, l+1)
			last = false
		}
	}
	if last {
		lastCnt++
		lastSum += l + 1
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var res float64

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	dfs(adj, 0, -1, 0, 1.0)
	fmt.Printf("%+v", res)
}

func dfs(adj [][]int, cur, from, l int, prob float64) {
	cnt := 0
	for _, v := range adj[cur] {
		if v != from {
			cnt++
		}
	}
	if cnt == 0 {
		res += float64(l) * prob
		return
	}
	for _, v := range adj[cur] {
		if v != from {
			dfs(adj, v, cur, l+1, prob/float64(cnt))
		}
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var lastSum int
var lastCnt int

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	vis := make(map[int]bool)
	dfs(adj, 0, -1, 0, vis)
	fmt.Printf("%+v", float64(lastSum)/float64(lastCnt))
}

func dfs(adj [][]int, cur, from, l int, vis map[int]bool) {
	vis[cur] = true
	last := true
	for _, v := range adj[cur] {
		if v != from && vis[v] == false {
			dfs(adj, v, cur, l+1, vis)
			last = false
		}
	}
	if last {
		lastCnt++
		lastSum += l
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var res float64

func solve() {
	n := readInt()
	adj := make([][]int, n)
	for i := 0; i < n-1; i++ {
		u := readInt() - 1
		v := readInt() - 1
		adj[u] = append(adj[u], v)
	}
	dfs(adj, 0, -1, 0, 1.0)
	fmt.Printf("%f", res)
}

func dfs(adj [][]int, cur, from, l int, prob float64) {
	cnt := 0
	for _, v := range adj[cur] {
		if v != from {
			cnt++
		}
	}
	if cnt == 0 {
		res += float64(l) * prob
		return
	}
	for _, v := range adj[cur] {
		if v != from {
			dfs(adj, v, cur, l+1, prob/float64(cnt))
		}
	}
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

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

	fmt.Printf("%f", dfs(adj, 0, -1))
}

func dfs(adj [][]int, cur, from int) float64 {
	cnt := 0
	var sum float64
	for _, v := range adj[cur] {
		if v != from {
			sum += dfs(adj, v, cur) + float64(1)
			cnt++
		}
	}
	if cnt != 0 {
		sum /= float64(cnt)
	}
	return sum
}

var scanner *bufio.Scanner

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	const MaxTokenLength = 1024 * 1024
	scanner.Buffer(make([]byte, 0, MaxTokenLength), MaxTokenLength)
	scanner.Split(bufio.ScanWords)
	solve()
}

// IO

func readString() string {
	scanner.Scan()
	return scanner.Text()
}

func readInt() int {
	val, _ := strconv.Atoi(readString())
	return val
}

func readInt64() int64 {
	v, _ := strconv.ParseInt(readString(), 10, 64)
	return v
}

func readIntArray(sz int) []int {
	a := make([]int, sz)
	for i := 0; i < sz; i++ {
		a[i] = readInt()
	}
	return a
}

func readInt64Array(n int) []int64 {
	res := make([]int64, n)
	for i := 0; i < n; i++ {
		res[i] = readInt64()
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type tuple struct {
	node         int
	branch_count int64
}

func main() {
	sc := NewScanner()
	N := sc.NextInt()
	edge := make([][]int, N)
	for i := 0; i < N; i++ {
		edge[i] = make([]int, 0)
	}
	for i := 0; i < N-1; i++ {
		a, b := sc.NextInt()-1, sc.NextInt()-1
		edge[a] = append(edge[a], b)
		edge[b] = append(edge[b], a)
	}

	checked := make([]bool, N)
	queue := make([]tuple, 1)
	queue[0] = tuple{0, 1}
	checked[0] = true
	count := 0
	p := 0

	ans := 0.0

	for {
		last := len(queue)
		if p == last {
			break
		}
		for ; p < last; p++ {
			branch_count := len(edge[queue[p].node]) - 1
			if p == 0 {
				branch_count++
			}
			for _, nx := range edge[queue[p].node] {
				if !checked[nx] {
					queue = append(queue, tuple{nx, queue[p].branch_count * int64(branch_count)})
					checked[nx] = true
				}
			}
			if branch_count == 0 {
				ans += float64(count) / float64(queue[p].branch_count)
			}
		}
		count++
	}
	fmt.Println(ans)
}

type Scanner struct {
	r   *bufio.Reader
	buf []byte
	p   int
}

func NewScanner() *Scanner {
	rdr := bufio.NewReaderSize(os.Stdin, 1000)
	return &Scanner{r: rdr}
}
func (s *Scanner) Next() string {
	s.pre()
	start := s.p
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}
	result := string(s.buf[start:s.p])
	s.p++
	return result
}
func (s *Scanner) NextLine() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)
	return string(s.buf[start:])
}
func (s *Scanner) NextInt() int {
	v, _ := strconv.Atoi(s.Next())
	return v
}
func (s *Scanner) NextInt64() int64 {
	v, _ := strconv.ParseInt(s.Next(), 10, 64)
	return v
}

func (s *Scanner) NextIntArray() []int {
	s.pre()
	start := s.p
	result := []int{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 0)
			result = append(result, int(v))
			start = s.p + 1
		}
	}

	return result
}
func (s *Scanner) NextInt64Array() []int64 {
	s.pre()
	start := s.p
	result := []int64{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 64)
			result = append(result, v)
			start = s.p + 1
		}
	}
	return result
}

func (s *Scanner) NextMap() map[int]bool {
	s.pre()
	start := s.p
	mp := map[int]bool{}
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			v, _ := strconv.Atoi(string(s.buf[start:s.p]))
			mp[v] = true
			start = s.p + 1
		}
	}
	v, _ := strconv.Atoi(string(s.buf[start:s.p]))
	mp[v] = true

	return mp
}

func (s *Scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}
func (s *Scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type tuple struct {
	edge         int
	branch_count int
}

func main() {
	sc := NewScanner()
	N := sc.NextInt()
	edge := make([][]int, N)
	for i := 0; i < N; i++ {
		edge[i] = make([]int, 0)
	}
	for i := 0; i < N-1; i++ {
		a, b := sc.NextInt()-1, sc.NextInt()-1
		edge[a] = append(edge[a], b)
		edge[b] = append(edge[b], a)
	}

	checked := make([]bool, N)
	queue := make([]tuple, 1)
	queue[0] = tuple{0, 1}
	checked[0] = true
	count := 0
	p := 0

	ans := 0.0

	for {
		last := len(queue)
		if p == last {
			break
		}
		for ; p < last; p++ {
			branch_count := len(edge[queue[p].edge]) - 1
			if p == 0 {
				branch_count++
			}
			for _, nx := range edge[queue[p].edge] {
				if !checked[nx] {
					queue = append(queue, tuple{nx, queue[p].branch_count * branch_count})
					checked[nx] = true
				}
			}
			if branch_count == 0 {
				ans += float64(count) / float64(queue[p].branch_count)
			}
		}
		count++
	}
	fmt.Println(ans)
}

type Scanner struct {
	r   *bufio.Reader
	buf []byte
	p   int
}

func NewScanner() *Scanner {
	rdr := bufio.NewReaderSize(os.Stdin, 1000)
	return &Scanner{r: rdr}
}
func (s *Scanner) Next() string {
	s.pre()
	start := s.p
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}
	result := string(s.buf[start:s.p])
	s.p++
	return result
}
func (s *Scanner) NextLine() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)
	return string(s.buf[start:])
}
func (s *Scanner) NextInt() int {
	v, _ := strconv.Atoi(s.Next())
	return v
}
func (s *Scanner) NextInt64() int64 {
	v, _ := strconv.ParseInt(s.Next(), 10, 64)
	return v
}

func (s *Scanner) NextIntArray() []int {
	s.pre()
	start := s.p
	result := []int{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 0)
			result = append(result, int(v))
			start = s.p + 1
		}
	}

	return result
}
func (s *Scanner) NextInt64Array() []int64 {
	s.pre()
	start := s.p
	result := []int64{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 64)
			result = append(result, v)
			start = s.p + 1
		}
	}
	return result
}

func (s *Scanner) NextMap() map[int]bool {
	s.pre()
	start := s.p
	mp := map[int]bool{}
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			v, _ := strconv.Atoi(string(s.buf[start:s.p]))
			mp[v] = true
			start = s.p + 1
		}
	}
	v, _ := strconv.Atoi(string(s.buf[start:s.p]))
	mp[v] = true

	return mp
}

func (s *Scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}
func (s *Scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func main() {
	sc := NewScanner()
	N := sc.NextInt()
	edge := make([][]int, N)
	for i := 0; i < N; i++ {
		edge[i] = make([]int, 0)
	}
	for i := 0; i < N-1; i++ {
		a, b := sc.NextInt()-1, sc.NextInt()-1
		edge[a] = append(edge[a], b)
		edge[b] = append(edge[b], a)
	}

	checked := make([]float64, N)
	queue := make([]int, 1)
	queue[0] = 0
	checked[0] = 1
	count := 0
	p := 0

	ans := 0.0
	for {
		last := len(queue)
		if p == last {
			break
		}
		for ; p < last; p++ {
			branch_count := len(edge[queue[p]]) - 1
			if p == 0 {
				branch_count++
			}
			for _, nx := range edge[queue[p]] {
				if checked[nx] == 0 {
					queue = append(queue, nx)
					checked[nx] = checked[queue[p]] * 1 / float64(branch_count)
				}
			}
			if branch_count == 0 {
				ans += checked[queue[p]] * float64(count)
			}
		}
		count++
	}
	fmt.Println(ans)
}

type Scanner struct {
	r   *bufio.Reader
	buf []byte
	p   int
}

func NewScanner() *Scanner {
	rdr := bufio.NewReaderSize(os.Stdin, 1000)
	return &Scanner{r: rdr}
}
func (s *Scanner) Next() string {
	s.pre()
	start := s.p
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}
	result := string(s.buf[start:s.p])
	s.p++
	return result
}
func (s *Scanner) NextLine() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)
	return string(s.buf[start:])
}
func (s *Scanner) NextInt() int {
	v, _ := strconv.Atoi(s.Next())
	return v
}
func (s *Scanner) NextInt64() int64 {
	v, _ := strconv.ParseInt(s.Next(), 10, 64)
	return v
}

func (s *Scanner) NextIntArray() []int {
	s.pre()
	start := s.p
	result := []int{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 0)
			result = append(result, int(v))
			start = s.p + 1
		}
	}

	return result
}
func (s *Scanner) NextInt64Array() []int64 {
	s.pre()
	start := s.p
	result := []int64{}
	for ; s.p < len(s.buf)+1; s.p++ {
		if s.p == len(s.buf) || s.buf[s.p] == ' ' {
			v, _ := strconv.ParseInt(string(s.buf[start:s.p]), 10, 64)
			result = append(result, v)
			start = s.p + 1
		}
	}
	return result
}

func (s *Scanner) NextMap() map[int]bool {
	s.pre()
	start := s.p
	mp := map[int]bool{}
	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			v, _ := strconv.Atoi(string(s.buf[start:s.p]))
			mp[v] = true
			start = s.p + 1
		}
	}
	v, _ := strconv.Atoi(string(s.buf[start:s.p]))
	mp[v] = true

	return mp
}

func (s *Scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}
func (s *Scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}


You are given a tree (connected graph without cycles) consisting of $$$n$$$ vertices. The tree is unrooted — it is just a connected undirected graph without cycles.In one move, you can choose exactly $$$k$$$ leaves (leaf is such a vertex that is connected to only one another vertex) connected to the same vertex and remove them with edges incident to them. I.e. you choose such leaves $$$u_1, u_2, \dots, u_k$$$ that there are edges $$$(u_1, v)$$$, $$$(u_2, v)$$$, $$$\dots$$$, $$$(u_k, v)$$$ and remove these leaves and these edges.Your task is to find the maximum number of moves you can perform if you remove leaves optimally.You have to answer $$$t$$$ independent test cases.

The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 2 \cdot 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow. The first line of the test case contains two integers $$$n$$$ and $$$k$$$ ($$$2 \le n \le 2 \cdot 10^5$$$; $$$1 \le k < n$$$) — the number of vertices in the tree and the number of leaves you remove in one move, respectively. The next $$$n-1$$$ lines describe edges. The $$$i$$$-th edge is represented as two integers $$$x_i$$$ and $$$y_i$$$ ($$$1 \le x_i, y_i \le n$$$), where $$$x_i$$$ and $$$y_i$$$ are vertices the $$$i$$$-th edge connects. It is guaranteed that the given set of edges forms a tree. It is guaranteed that the sum of $$$n$$$ does not exceed $$$2 \cdot 10^5$$$ ($$$\sum n \le 2 \cdot 10^5$$$).

For each test case, print the answer — the maximum number of moves you can perform if you remove leaves optimally.

NoteThe picture corresponding to the first test case of the example:There you can remove vertices $$$2$$$, $$$5$$$ and $$$3$$$ during the first move and vertices $$$1$$$, $$$7$$$ and $$$4$$$ during the second move.The picture corresponding to the second test case of the example:There you can remove vertices $$$7$$$, $$$8$$$ and $$$9$$$ during the first move, then vertices $$$5$$$, $$$6$$$ and $$$10$$$ during the second move and vertices $$$1$$$, $$$3$$$ and $$$4$$$ during the third move.The picture corresponding to the third test case of the example:There you can remove vertices $$$5$$$ and $$$7$$$ during the first move, then vertices $$$2$$$ and $$$4$$$ during the second move and vertices $$$1$$$ and $$$6$$$ during the third move.

package main

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

// Credits - github.com/EndlessCheng/codeforces-go
func solve(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	T:= 0
	for Fscan(in, &T); T > 0; T-- {
		var n,k int
		Fscan(in,&n,&k)
		e := make([][] int ,n)
		vis := make([] bool, n)
		stk := make([] int,0,n)
		deg := make([] int,n)
		ct := make([] int,n)
		ans:=0

		for i:=0;i<n-1;i++{
			var u,v int
			Fscan(in,&u,&v)
			u--
			v--
			deg[u]++
			deg[v]++
			e[u]=append(e[u],v)
			e[v]=append(e[v],u)
		}
		if k==1{
			Fprintln(out,n-1)
			continue
		}
		findPar := func(u int) int {
			for _,v := range(e[u]){
				if vis[v]{
					return v
				}
			}
			return -1
			// panic("No Parent")
		}

		for i:=0;i<n;i++{
			vis[i]=true
			if deg[i]==1{
				stk=append(stk,i)
			}
		}

		for i:=0;i<n-1;i++{
			if len(stk)==i{
				break
			}
			cur:=stk[i]
			vis[cur]=false
			// Fprintln(out,"remove",cur+1)
			par:=findPar(cur)
			deg[par]--
			deg[cur]--
			ct[par]++
			if ct[par]==k{
				ct[par]=0
				ans++
			}
			if deg[par]==1 && (len(e[par])-1)%k==0{
				stk=append(stk,par)
			}
		}

		Fprintln(out,ans)
	}
}

func main() { solve(os.Stdin, os.Stdout) }

package main

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

func main() {
	io := newFastIO(os.Stdin, os.Stdout)
	defer io.Flush()

	for t := io.nextInt(); t > 0; t-- {
		n, k := io.nextInt(), io.nextInt()
		g := make([][]int, n+1)
		deg := make([]int, n+1)
		for i := 0; i < n-1; i++ {
			u, v := io.nextInt(), io.nextInt()
			g[u] = append(g[u], v)
			g[v] = append(g[v], u)
			deg[u]++
			deg[v]++
		}

		var q []int
		for u := 1; u <= n; u++ {
			if deg[u] == 1 {
				q = append(q, u)
			}
		}

		ans := 0
		cnt := make([]int, n+1)
		ded := make([]bool, n+1)
		for len(q) > 0 {
			u := q[0]
			ded[u] = true
			q = q[1:]
			for _, p := range g[u] {
				if ded[p] {
					continue
				}
				cnt[p]++
				deg[p]--
				if cnt[p]%k == 0 {
					ans++
					if deg[p] == 1 {
						q = append(q, p)
					}
				}
			}
		}

		io.println(ans)
	}
}

type fastIO struct {
	*bufio.Reader
	*bufio.Writer
	p []byte
}

func newFastIO(r io.Reader, w io.Writer) fastIO {
	return fastIO{bufio.NewReader(r), bufio.NewWriter(w), make([]byte, 1)}
}

func (f *fastIO) nextInt() int {
	f.Read(f.p)
	for !('0' <= f.p[0] && f.p[0] <= '9') {
		f.Read(f.p)
	}
	n := 0
	for '0' <= f.p[0] && f.p[0] <= '9' {
		n = n*10 + int(f.p[0]) - '0'
		f.Read(f.p)
	}
	return n
}

func (f *fastIO) next() string {
	f.Read(f.p)
	for f.p[0] <= ' ' {
		f.Read(f.p)
	}
	var s []byte
	for f.p[0] > ' ' {
		s = append(s, f.p[0])
		f.Read(f.p)
	}
	return string(s)
}

func (f *fastIO) println(a ...interface{}) {
	fmt.Fprintln(f.Writer, a...)
}

func (f *fastIO) print(a ...interface{}) {
	fmt.Fprint(f.Writer, a...)
}

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1385F(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, k, v, w int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &k)
		g := make([][]int, n)
		for i := 1; i < n; i++ {
			Fscan(in, &v, &w)
			v--
			w--
			g[v] = append(g[v], w)
			g[w] = append(g[w], v)
		}
		if k == 1 {
			Fprintln(out, n-1)
			continue
		}

		ans := 0
		q := []int{}
		lc := make([]int, n)
		used := make([]bool, n)
		for v, vs := range g {
			for _, w := range vs {
				if len(g[w]) == 1 {
					lc[v]++
					used[w] = true
				}
			}
			if len(vs) > 1 && lc[v]+1 >= len(vs) && lc[v]%k == 0 {
				q = append(q, v)
			}
		}
		for len(q) > 0 {
			v, q = q[0], q[1:]
			ans += lc[v] / k
			lc[v] = 0
			used[v] = true
			for _, w := range g[v] {
				if !used[w] {
					lc[w]++
					if lc[w]+1 >= len(g[w]) && lc[w]%k == 0 {
						q = append(q, w)
					}
					break
				}
			}
		}
		for _, c := range lc {
			ans += c / k
		}
		Fprintln(out, ans)
	}
}

func main() { CF1385F(os.Stdin, os.Stdout) }

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1385F(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, k, v, w int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &k)
		g := make([][]int, n)
		for i := 1; i < n; i++ {
			Fscan(in, &v, &w)
			v--
			w--
			g[v] = append(g[v], w)
			g[w] = append(g[w], v)
		}
		if k == 1 {
			Fprintln(out, n-1)
			continue
		}
		if n == 2 {
			Fprintln(out, 0)
			continue
		}

		ans := 0
		q := []int{}
		onQ := make([]bool, n)
		lc := make([]int, n)
		isLeaf := make([]bool, n)
		for v, vs := range g {
			for _, w := range vs {
				if len(g[w]) == 1 {
					lc[v]++
					isLeaf[w] = true
				}
			}
			if lc[v] > 0 &&  lc[v]+1 >= len(vs) && lc[v]%k == 0 {
				q = append(q, v)
				onQ[v] = true
			}
		}
		for len(q) > 0 {
			v, q = q[0], q[1:]
			onQ[v] = false
			ans += lc[v] / k
			lc[v] = 0
			isLeaf[v] =true
			for _, w := range g[v] {
				if isLeaf[w] {
					continue
				}
				lc[w]++
				if lc[w]+1 >= len(g[w]) && lc[w]%k == 0 {
					if !onQ[w] {
						q = append(q, w)
						onQ[w] = true
					}
					//g[v] = []int{w}
					break
				}
			}
		}
		for _, c := range lc {
			ans += c / k
		}
		Fprintln(out, ans)
	}
}

func main() { CF1385F(os.Stdin, os.Stdout) }

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1385F(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, k, v, w int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &k)
		g := make([][]int, n)
		for i := 1; i < n; i++ {
			Fscan(in, &v, &w)
			v--
			w--
			g[v] = append(g[v], w)
			g[w] = append(g[w], v)
		}
		if k == 1 {
			Fprintln(out, n-1)
			continue
		}

		ans := 0
		q := []int{}
		lc := make([]int, n)
		for v, vs := range g {
			for _, w := range vs {
				if len(g[w]) == 1 {
					lc[v]++
				}
			}
			if lc[v]+1 >= len(vs) && lc[v] >= k {
				q = append(q, v)
			}
		}
		//Println(q)
		for len(q) > 0 {
			v, q = q[0], q[1:]
			if lc[v]%k == 0 {
				ans += lc[v] / k
				for _, w := range g[v] {
					if len(g[w]) > 1 && lc[w]+2 >= len(g[w]) {
						q = append(q, w)
						lc[w]++
						g[v] = []int{w}
						break
					}
				}
				lc[v] = 0
			}
		}
		for _, c := range lc {
			ans += c / k
		}
		Fprintln(out, ans)
	}
}

func main() { CF1385F(os.Stdin, os.Stdout) }

package main

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

// github.com/EndlessCheng/codeforces-go
func CF1385F(_r io.Reader, _w io.Writer) {
	in := bufio.NewReader(_r)
	out := bufio.NewWriter(_w)
	defer out.Flush()

	var t, n, k, v, w int
	for Fscan(in, &t); t > 0; t-- {
		Fscan(in, &n, &k)
		g := make([][]int, n)
		for i := 1; i < n; i++ {
			Fscan(in, &v, &w)
			v--
			w--
			g[v] = append(g[v], w)
			g[w] = append(g[w], v)
		}
		if k == 1 {
			Fprintln(out, n-1)
			continue
		}

		ans := 0
		q := []int{}
		lc := make([]int, n)
		for v, vs := range g {
			for _, w := range vs {
				if len(g[w]) == 1 {
					lc[v]++
				}
			}
			if lc[v]+1 >= len(vs) && lc[v] >= k {
				q = append(q, v)
			}
		}
		//Println(q)
		for len(q) > 0 {
			v, q = q[0], q[1:]
			ans += lc[v] / k
			if lc[v] > 0 && lc[v]%k == 0 {
				for _, w := range g[v] {
					if len(g[w]) > 1 && lc[w]+2 >= len(g[w]) {
						q = append(q, w)
						lc[w]++
						g[v] = []int{w}
						break
					}
				}
			}
			lc[v] %= k
		}
		// 收拾残局
		for _, c := range lc {
			ans += c / k
		}
		Fprintln(out, ans)
	}
}

func main() { CF1385F(os.Stdin, os.Stdout) }