#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
  in >> p.first >> p.second;
  return in;
}
template <typename T>
istream &operator>>(istream &in, vector<T> &v) {
  for (auto &x : v) in >> x;
  return in;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
  out << "[" << p.first << ", " << p.second << "]"
      << "\n";
  return out;
}
template <class T>
struct Edge {
  int from, to;
  T cost;
  Edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
  explicit operator int() const { return to; }
};
template <class T>
using Edges = vector<Edge<T>>;
template <class T>
using WeightedGraph = vector<Edges<T>>;
using UnWeightedGraph = vector<vector<int>>;
template <class T>
using DistMatrix = vector<vector<T>>;
struct GraphAdapter {
  template <class T>
  static UnWeightedGraph to_unweighted_graph(const WeightedGraph<T> &origin) {
    int V = origin.size();
    UnWeightedGraph graph(V);
    for (int i = 0; i < V; i++)
      for (auto &e : origin[i]) graph[i].push_back((int)e);
    return graph;
  }
  static WeightedGraph<int> to_weighted_graph(const UnWeightedGraph &origin) {
    int V = origin.size();
    WeightedGraph<int> graph(V);
    for (int i = 0; i < V; i++)
      for (auto to : origin[i]) graph[i].push_back({i, to, 1});
    return graph;
  }
  template <class T>
  static DistMatrix<T> to_dist_matrix(const WeightedGraph<T> &origin, T INF) {
    int V = origin.size();
    DistMatrix<T> matrix(V, vector<T>(V, INF));
    for (int i = 0; i < V; i++)
      for (auto &e : origin[i]) matrix[i][e.to] = e.cost;
    for (int i = 0; i < V; i++) matrix[i][i] = 0;
    return matrix;
  }
};
void dfs(int v, int p, int d, vector<int> &dist, UnWeightedGraph &G) {
  dist[v] = d;
  for (auto to : G[v]) {
    if (to == p) continue;
    dfs(to, v, d + 1, dist, G);
  }
}
bool dfs2(int v, int p, int aim, vector<int> &path, UnWeightedGraph &G) {
  if (v == aim) {
    path.push_back(v);
    return true;
  }
  for (auto to : G[v]) {
    if (to == p) continue;
    if (dfs2(to, v, aim, path, G)) {
      path.push_back(v);
      return true;
    }
  }
  return false;
}
constexpr int INF = 1e6;
int main() {
  int N;
  cin >> N;
  UnWeightedGraph G(N);
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  vector<int> dist(N);
  dfs(0, -1, 0, dist, G);
  int a = max_element(dist.begin(), dist.end()) - dist.begin();
  dfs(a, -1, 0, dist, G);
  int b = max_element(dist.begin(), dist.end()) - dist.begin();
  vector<int> path;
  dfs2(a, -1, b, path, G);
  if (path.size() == N) {
    cout << N - 1 << endl;
    cout << a + 1 << " " << path[1] + 1 << " " << b + 1 << endl;
    return 0;
  }
  dist = vector<int>(N, INF);
  queue<int> Q;
  for (auto x : path) {
    dist[x] = 0;
    Q.push(x);
  }
  while (!Q.empty()) {
    int v = Q.front();
    Q.pop();
    for (auto to : G[v]) {
      if (dist[to] != INF) continue;
      dist[to] = dist[v] + 1;
      Q.push(to);
    }
  }
  int c = max_element(dist.begin(), dist.end()) - dist.begin();
  cout << path.size() - 1 + dist[c] << endl;
  cout << a + 1 << " " << b + 1 << " " << c + 1 << endl;
}
