import java.io.*;
import java.util.*;

/**
 * @author Roman V Satyukov
 */
public class collider_rs implements Runnable {
	private final String problemID = getClass().getName().split("_")[0].toLowerCase();
	private static final int inf = Integer.MAX_VALUE / 5;
	private BufferedReader in;
	private PrintWriter out;
	private List<Integer>[] nei;
	
	// Максимум вниз
	private int[] maxDepth;
	private int[] maxDepthMove;
	
	// Максимум вниз + путь
	private int[] maxDepthPath;
	private int[] maxDepthPathMove1;
	private int[] maxDepthPathMove2;
	
	// Путь
	private int[] maxPath;
	private int[] maxPathMove1;
	private int[] maxPathMove2;
	
	// Два пути
	private int[] max2Path;
	private int[] max2PathMove1;
	private int[] max2PathMove2;
	private int[] max2PathMove3;
	
	private int[] children;
	
	private void check(boolean expr, String message) {
		if (!expr) {
			throw new AssertionError(message);
		}
	}
	
	// Максимум вниз, путь
	private void process1(int u, int p) {
		maxDepth[u] = 1;
		maxDepthMove[u] = u;
		maxPath[u] = 1;
		maxPathMove1[u] = -1;
		maxPathMove2[u] = -1;
		int max1 = -1;
		int max2 = -1;
		for (int v: nei[u]) {
			if (v == p) {
				continue;
			}
			process1(v, u);
			if (maxDepth[v] + 1 > maxDepth[u]) {
				maxDepth[u] = maxDepth[v] + 1;
				maxDepthMove[u] = v;
			}
			if (maxPath[v] > maxPath[u]) {
				maxPath[u] = maxPath[v];
				maxPathMove1[u] = v;
				maxPathMove2[u] = -1;
			}
			if (max1 == -1 || maxDepth[v] > maxDepth[max1]) {
				max2 = max1;
				max1 = v;
			} else if (max2 == -1 || maxDepth[v] > maxDepth[max2]) {
				max2 = v;
			}
		}
		if (maxDepth[u] > maxPath[u]) {
			maxPath[u] = maxDepth[u];
			maxPathMove1[u] = -1;
			maxPathMove2[u] = -1;
		}
		if (max2 != -1 && maxDepth[max1] + maxDepth[max2] + 1 > maxPath[u]) {
			maxPath[u] = maxDepth[max1] + maxDepth[max2] + 1;
			maxPathMove1[u] = max1;
			maxPathMove2[u] = max2;
		}
	}

	// Самая низкая точка пути вниз
	private int getDeepestPoint(int u) {
		if (maxDepth[u] == 1) {
			return u;
		} else {
			return getDeepestPoint(maxDepthMove[u]);
		}
	}

	// Концы максимального пути
	private int[] getLongestPathEndpoints(int u) {
		if (maxPathMove1[u] >= 0 && maxPathMove2[u] == -1) {
			return getLongestPathEndpoints(maxPathMove1[u]);
		}
		if (maxPathMove1[u] == -1 && maxPathMove2[u] == -1) {
			return new int[] { u, getDeepestPoint(u) };
		}
		return new int[] { getDeepestPoint(maxPathMove1[u]), getDeepestPoint(maxPathMove2[u]) };  
	}

	// Максимум вниз + путь, два пути
	private void process2(int u, int p) {
		int max1 = -1;
		int max2 = -1;
		max2Path[u] = -inf;
		maxDepthPath[u] = -inf;
		for (int v: nei[u]) {
			if (v == p) {
				continue;
			}
			process2(v, u);
			if (max2Path[v] > max2Path[u]) {
				max2Path[u] = max2Path[v];
				max2PathMove1[u] = v;
				max2PathMove2[u] = -1;
				max2PathMove3[u] = -1;
			}
			if (maxDepthPath[v] + 1 > maxDepthPath[u]) {
				maxDepthPath[u] = maxDepthPath[v] + 1;
				maxDepthPathMove1[u] = v;
				maxDepthPathMove2[u] = -1;
			}
			if (max1 == -1 || maxPath[v] > maxPath[max1]) {
				max2 = max1;
				max1 = v;
			} else if (max2 == -1 || maxPath[v] > maxPath[max2]) {
				max2 = v;
			}
		}
		if (max2 != -1 && maxPath[max1] + maxPath[max2] > max2Path[u]) {
			max2Path[u] = maxPath[max1] + maxPath[max2];
			max2PathMove1[u] = max1;
			max2PathMove2[u] = max2;
			max2PathMove3[u] = -1;
		}
		
		int num = 0;	
		for (int v: nei[u]) {
			if (v == p) {
				continue;
			}
			children[num++] = v;
		}
		
		if (maxDepthPath[u] > max2Path[u]) {
			max2Path[u] = maxDepthPath[u];
			max2PathMove1[u] = -1;
			max2PathMove2[u] = -1;
			max2PathMove3[u] = -1;
		}
		
		if (num <= 1) {
			return;
		}
		
		max1 = -1;
		max2 = -1;
		int max3 = -1;
		for (int i = 0; i < num; i++) {
			if (max1 == -1 || maxDepth[children[i]] > maxDepth[children[max1]]) {
				max3 = max2;
				max2 = max1;
				max1 = i;
			} else if (max2 == -1 || maxDepth[children[i]] > maxDepth[children[max2]]) {
				max3 = max2;
				max2 = i;
			} else if (max3 == -1 || maxDepth[children[i]] > maxDepth[children[max3]]) {
				max3 = i;
			}
		}
		
		for (int i = 0; i < num; i++) {
			int a;
			if (i == max1) {
				a = max2;
			} else {
				a = max1;
			}
			if (maxDepthPath[children[i]] + maxDepth[children[a]] + 1 > max2Path[u]) {
				max2Path[u] = maxDepthPath[children[i]] + maxDepth[children[a]] + 1;
				max2PathMove1[u] = -1;
				max2PathMove2[u] = children[i];
				max2PathMove3[u] = children[a];
			}
			if (maxPath[children[i]] + maxDepth[children[a]] + 1 > maxDepthPath[u]) {
				maxDepthPath[u] = maxPath[children[i]] + maxDepth[children[a]] + 1;
				maxDepthPathMove1[u] = children[a];
				maxDepthPathMove2[u] = children[i];
			}
		}
		
		if (maxDepthPath[u] > max2Path[u]) {
			max2Path[u] = maxDepthPath[u];
			max2PathMove1[u] = -1;
			max2PathMove2[u] = -1;
			max2PathMove3[u] = -1;
		}
		
		if (num <= 2) {
			return;
		}
		
		for (int i = 0; i < num; i++) {
			int a, b;
			if (i == max1) {
				a = max2;
				b = max3;
			} else if (i == max2) {
				a = max1;
				b = max3;
			} else {
				a = max1;
				b = max2;
			}
			if (maxDepth[children[a]] + maxDepth[children[b]] + 1 + maxPath[children[i]] > max2Path[u]) {
				max2Path[u] = maxDepth[children[a]] + maxDepth[children[b]] + 1 + maxPath[children[i]];
				max2PathMove1[u] = children[i];
				max2PathMove2[u] = children[a];
				max2PathMove3[u] = children[b];
			}
		}
	}

	private int[] getLongestDepthPathEndpoints(int u) {
		if (maxDepthPathMove1[u] >= 0 && maxDepthPathMove2[u] == -1) {
			return getLongestDepthPathEndpoints(maxDepthPathMove1[u]);
		}
		int[] tmp = getLongestPathEndpoints(maxDepthPathMove2[u]);
		return new int[] { getDeepestPoint(maxDepthPathMove1[u]), tmp[0], tmp[1] }; 
	}

	private int[] getLongest2PathEndpoints(int u) {
		if (max2PathMove1[u] >= 0 && max2PathMove2[u] == -1 && max2PathMove3[u] == -1) {
			return getLongest2PathEndpoints(max2PathMove1[u]);
		}
		if (max2PathMove1[u] >= 0 && max2PathMove2[u] >= 0 && max2PathMove3[u] == -1) {
			int[] tmp1 = getLongestPathEndpoints(max2PathMove1[u]);
			int[] tmp2 = getLongestPathEndpoints(max2PathMove2[u]);
			return new int[] { tmp1[0], tmp2[0], tmp1[1], tmp2[1] };
		}
		if (max2PathMove1[u] == -1 && max2PathMove2[u] >= 0 && max2PathMove3[u] >= 0) {
			int[] tmp = getLongestDepthPathEndpoints(max2PathMove2[u]);
			return new int[] { tmp[0], tmp[1], tmp[2], getDeepestPoint(max2PathMove3[u])};
		}
		if (max2PathMove1[u] == -1 && max2PathMove2[u] == -1 && max2PathMove3[u] == -1) {
			int[] tmp = getLongestDepthPathEndpoints(u);
			return new int[] { u, tmp[1], tmp[0], tmp[2] };
		}
		
		int[] tmp = getLongestPathEndpoints(max2PathMove1[u]);
		return new int[] { tmp[0], getDeepestPoint(max2PathMove2[u]), tmp[1], getDeepestPoint(max2PathMove3[u]) };
	}

	@SuppressWarnings("unchecked")
	private void solve() throws IOException {
		int n = Integer.parseInt(in.readLine());
		check((3 <= n) && (n <= 100000), "n is not in [3..100,000]");
		nei = new List[n];
		for (int i = 0; i < n; i++) {
			nei[i] = new ArrayList<Integer>();
		}
		for (int i = 0; i < n - 1; i++) {
			StringTokenizer st = new StringTokenizer(in.readLine());
			int u = Integer.parseInt(st.nextToken()) - 1;
			int v = Integer.parseInt(st.nextToken()) - 1;
			nei[u].add(v);
			nei[v].add(u);
		}
		
		maxDepth = new int[n];
		maxDepthMove = new int[n];
		
		maxPath = new int[n];
		maxPathMove1 = new int[n];
		maxPathMove2 = new int[n];
		process1(0, -1);
		
		maxDepthPath = new int[n];
		maxDepthPathMove1 = new int[n];
		maxDepthPathMove2 = new int[n];
		max2Path = new int[n];
		max2PathMove1 = new int[n];
		max2PathMove2 = new int[n];
		max2PathMove3 = new int[n];
		children = new int[n];
		process2(0, -1);
		
		if (maxPath[0] > max2Path[0]) {
			out.println(maxPath[0]);
			int[] tmp = getLongestPathEndpoints(0);
			tmp[0]++;
			tmp[1]++;
			out.println(tmp[0] + " " + tmp[1]);
		} else {
			out.println(max2Path[0]);
			int[] tmp = getLongest2PathEndpoints(0);
			for (int i = 0; i < tmp.length; i++) {
				tmp[i]++;
			}
			if (!nei[tmp[0] - 1].contains(tmp[1] - 1)) {
				out.println(tmp[0] + " " + tmp[1]);
			}
			if (!nei[tmp[2] - 1].contains(tmp[3] - 1)) {
				out.println(tmp[2] + " " + tmp[3]);
			}
		}
	}
	
	public static void main(String[] args) {
		new Thread(new collider_rs()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new FileReader(new File(problemID + ".in")));
			out = new PrintWriter(new File(problemID + ".out"));
			solve();
			in.close();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}
}
