```go
package main
import (
"bufio"
"fmt"
"os"
)
type FastScanner struct {
r *bufio.Reader
}
func NewFastScanner() *FastScanner {
return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}
func (fs *FastScanner) NextInt() int {
sign, val := 1, 0
c, _ := fs.r.ReadByte()
for (c < '0' || c > '9') && c != '-' {
c, _ = fs.r.ReadByte()
}
if c == '-' {
sign = -1
c, _ = fs.r.ReadByte()
}
for c >= '0' && c <= '9' {
val = val*10 + int(c-'0')
c2, err := fs.r.ReadByte()
if err != nil {
return sign * val
}
c = c2
}
fs.r.UnreadByte()
return sign * val
}
func bfsFarthest(adj [][]int, start int) (far int, dist []int, parent []int) {
n := len(adj) - 1
dist = make([]int, n+1)
parent = make([]int, n+1)
for i := 1; i <= n; i++ {
dist[i] = -1
parent[i] = 0
}
q := make([]int, 0, n)
dist[start] = 0
q = append(q, start)
head := 0
for head < len(q) {
v := q[head]
head++
for _, to := range adj[v] {
if dist[to] == -1 {
dist[to] = dist[v] + 1
parent[to] = v
q = append(q, to)
}
}
}
far = start
for i := 1; i <= n; i++ {
if dist[i] > dist[far] {
far = i
}
}
return
}
func bfsWithBlocked(adj [][]int, start int, blocked []bool) (far int, dist []int) {
n := len(adj) - 1
dist = make([]int, n+1)
for i := 1; i <= n; i++ {
dist[i] = -1
}
if blocked[start] {
return start, dist
}
q := make([]int, 0, n)
dist[start] = 0
q = append(q, start)
head := 0
for head < len(q) {
v := q[head]
head++
for _, to := range adj[v] {
if blocked[to] || dist[to] != -1 {
continue
}
dist[to] = dist[v] + 1
q = append(q, to)
}
}
far = start
for i := 1; i <= n; i++ {
if dist[i] > dist[far] {
far = i
}
}
return
}
func main() {
fs := NewFastScanner()
n := fs.NextInt()
adj := make([][]int, n+1)
for i := 0; i < n-1; i++ {
a := fs.NextInt()
b := fs.NextInt()
adj[a] = append(adj[a], b)
adj[b] = append(adj[b], a)
}
u, _, _ := bfsFarthest(adj, 1)
v, distU, parentU := bfsFarthest(adj, u)
diamLen := distU[v]
onPath := make([]bool, n+1)
cur := v
for cur != 0 {
onPath[cur] = true
if cur == u {
break
}
cur = parentU[cur]
}
a := u
b := v
c := 1
_, distFromPath := bfsWithBlocked(adj, u, onPath)
bestDist := -1
bestNode := -1
for i := 1; i <= n; i++ {
if distFromPath[i] > bestDist {
bestDist = distFromPath[i]
bestNode = i
}
}
if bestNode == -1 {
for i := 1; i <= n; i++ {
if i != a && i != b {
bestNode = i
break
}
}
bestDist = 0
}
c = bestNode
res := diamLen + bestDist
if bestDist == -1 {
res = diamLen
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
fmt.Fprintln(out, res)
fmt.Fprintln(out, a, b, c)
out.Flush()
}
```