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

/**
 * @author Roman V Satyukov
 */
public class collider_rs_bug1 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;
        maxPath[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]) {
                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_bug1()).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);
        }
    }
}
