#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md;
ll dep[DIM];
ll p[21][DIM];
ll tin[DIM];
ll tout[DIM];
ll timer;ll A,B,C;
void dfs(ll v, ll dist, ll par, ll t, ll lvl)
{
    if(dist>md)
    {

        if(t==2 && v==A);
        else{
        md=dist;
        k=v;
        }
    }

    if(t==1)
    {
        timer++;

        tin[v]=timer;

        dep[v]=lvl;

        p[0][v]=par;

        for(int i=1; i<=20; i++)
        {

            p[i][v]=p[i-1][p[i-1][v]];
            //cout << v << " " << i << " " << p[i][v] << endl;
        }
    }
    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t,lvl+1);
        }
    }
    if(t==1)
        tout[v]=++timer;
}

ll upper(ll v1, ll v2){
    return (tin[v1]<=tin[v2] && tout[v2]<=tout[v1]);
}

ll lca(ll v1, ll v2)
{
    if(upper(v1,v2)) return v1;
    if(upper(v2,v1)) return v2;

    for(int i=20; i>=0; i--){
        if(!upper(p[i][v1],v2)) v1=p[i][v1];
    }
    return p[0][v1];
}

int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;
    dfs(1,0,1,1,1);
    A=k;
    md=0;
    k=A;
    dfs(A,0,1,2,1);
    B=k;
    //cout << A << " " << B << " " << md << endl;

    ll p1,p2,Z;
    ll res=0;
    for(int i=1; i<=n; i++){

        if(i==A || i==B) continue;

        p1=lca(i,A);
        p2=lca(i,B);

        if(p1==i || p2==i) continue;

        Z=min(dep[i]-dep[p1]    ,dep[i]-dep[p2]   );
        if(Z>res){
            res=Z;
            C=i;
        }
    }

    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef int ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md,res;
ll A,B,C;
ll p[DIM];

vector<ll> diametr;
void dfs(ll v, ll dist, ll par, ll t)
{
    p[v]=par;
    if(dist>md)
    {
        md=dist;
        k=v;
    }

    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t);
        }
    }
}

ll D1[DIM];
ll now;
ll D2[DIM];

void check(ll v, ll par, ll dist){

    if(dist>res){
        res=dist;
        C=v;
    }
    for(auto to:a[v]){
        if(to==par) continue;
        //cout << to << " TO " << diametr[now+1] << endl;
        if(to==diametr[now+1]){
            continue;
        }
        check(to,v,dist+1);
    }
}

int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        D1[i]=v1;
        D2[i]=v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;

    dfs(1,0,1,1);

    A=k;

    md=0;

    k=A;

    dfs(A,0,A,2);

    B=k;

    ll v=B;

    while(v!=A)
    {
        diametr.push_back(v);
        v=p[v];
    }
    diametr.push_back(A);
    if(diametr.size()==n-1)
    {
        for(int i=1; i<=n; i++)
            if(A!=i && B!=i)
            {

                cout << n-1 << endl << A << " " << B << " " << i << endl;
                return 0;
            }
    }

    diametr.push_back(0);
    now=1;
    for(int i=0; i<diametr.size()-1; i++){
        ll to=diametr[i];
        now=i;
        if(i==0) check(to,to,0);
        else check(to,diametr[i-1],0);
        //cout << i << " " << diametr[i] << " " << res << endl;

    }
    //cout << md << endl;
    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md;
ll dep[DIM];
ll p[21][DIM];
ll tin[DIM];
ll tout[DIM];
ll timer;
void dfs(ll v, ll dist, ll par, ll t, ll lvl)
{
    if(dist>md)
    {
        md=dist;
        k=v;
    }

    if(t==1)
    {
        timer++;

        tin[v]=timer;

        dep[v]=lvl;

        p[0][v]=par;

        for(int i=1; i<=20; i++)
        {

            p[i][v]=p[i-1][p[i-1][v]];
            //cout << v << " " << i << " " << p[i][v] << endl;
        }
    }
    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t,lvl+1);
        }
    }
    if(t==1)
        tout[v]=++timer;
}

ll upper(ll v1, ll v2){
    return (tin[v1]<=tin[v2] && tout[v2]<=tout[v1]);
}

ll lca(ll v1, ll v2)
{
    if(upper(v1,v2)) return v1;
    if(upper(v2,v1)) return v2;

    for(int i=20; i>=0; i--){
        if(!upper(p[i][v1],v2)) v1=p[i][v1];
    }
    return p[0][v1];
}
ll A,B,C;
int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;
    dfs(1,0,1,1,1);
    A=k;
    md=0;
    k=A;
    dfs(A,0,1,2,1);
    B=k;
    //cout << A << " " << B << " " << md << endl;

    ll p1,p2,Z;
    ll res=0;
    for(int i=1; i<=n; i++){

        if(i==A || i==B) continue;

        p1=lca(i,A);
        p2=lca(i,B);

        if(p1==i || p2==i) continue;

        Z=min(dep[i]-dep[p1]    ,dep[i]-dep[p2]   );
        if(Z>res){
            res=Z;
            C=i;
        }
    }

    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md;
ll dep[DIM];
ll p[21][DIM];
ll tin[DIM];
ll tout[DIM];
ll timer;ll A,B,C;
void dfs(ll v, ll dist, ll par, ll t)
{
    if(dist>md)
    {

        if(t==2 && v==A);
        else{
        md=dist;
        k=v;
        }
    }

    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t);
        }
    }
}

void calclca(ll v, ll par, ll lvl){

        timer++;

        tin[v]=timer;

        dep[v]=lvl;

        p[0][v]=par;
        //cout << par << endl;
        for(int i=1; i<=20; i++)
        {

            p[i][v]=p[i-1][p[i-1][v]];
            //cout << v << " " << i << " " << p[i][v] << endl;
        }

    for(auto to:a[v]){

        if(to!=par) calclca(to,v,lvl+1);
    }
    tout[v]=++timer;
}

ll upper(ll v1, ll v2){
    return (tin[v1]<=tin[v2] && tout[v2]<=tout[v1]);
}

ll lca(ll v1, ll v2)
{
    if(upper(v1,v2)) return v1;
    if(upper(v2,v1)) return v2;

    for(int i=20; i>=0; i--){
        if(!upper(p[i][v1],v2)) v1=p[i][v1];
    }
    //cout << v1 << "V!1" << endl;
    //cout << p[0][v1] << "PV1" << endl;
    return p[0][v1];
}

int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;

    calclca(1,1,0);
    dfs(1,0,1,1);
    A=k;
    md=0;
    k=A;
    dfs(A,0,A,2);
    B=k;
    //cout << A << " " << B << " " << md << endl;

    ll p1,p2,Z;
    ll res=0;

    //cout << lca(2,4) << endl;
    ll opa=lca(A,B);
    for(int i=1; i<=n; i++){

        if(i==A || i==B) continue;
        if(C==0) C=i;
        p1=lca(i,A);
        p2=lca(i,B);

        if(p1==i && p2!=i) continue;
        if(p1!=i && p2==i) continue;

        if(p1==i && p2==i){

            Z=abs(dep[opa]-dep[i]);
            if(Z>res){
            res=Z;
            C=i;
        }

            continue;
        }
        //cout << i << " " << p1 << " " << p2 << endl;
        Z=min(dep[i]-dep[p1]    ,dep[i]-dep[p2]   );
        if(Z>res){
            res=Z;
            C=i;
        }
    }

    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef int ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md;
ll dep[DIM];
ll p[21][DIM];
ll tin[DIM];
ll tout[DIM];
ll timer;ll A,B,C;
void dfs(ll v, ll dist, ll par, ll t)
{
    if(dist>md)
    {
        md=dist;
        k=v;
    }

    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t);
        }
    }
}

void calclca(ll v, ll par, ll lvl){

        timer++;

        tin[v]=timer;

        dep[v]=lvl;

        p[0][v]=par;
        //cout << par << endl;
        for(int i=1; i<=20; i++)
        {

            p[i][v]=p[i-1][p[i-1][v]];
            //cout << v << " " << i << " " << p[i][v] << endl;
        }

    for(auto to:a[v]){

        if(to!=par) calclca(to,v,lvl+1);
    }
    tout[v]=++timer;
}

ll upper(ll v1, ll v2){
    return (tin[v1]<=tin[v2] && tout[v2]<=tout[v1]);
}

ll lca(ll v1, ll v2)
{
    if(upper(v1,v2)) return v1;
    if(upper(v2,v1)) return v2;

    for(int i=20; i>=0; i--){
        if(!upper(p[i][v1],v2)) v1=p[i][v1];
    }
    //cout << v1 << "V!1" << endl;
    //cout << p[0][v1] << "PV1" << endl;
    return p[0][v1];
}
ll D1[DIM];
ll D2[DIM];

ll check(ll v, ll v1, ll v2){

    ll k1=lca(v1,v);
    ll k2=lca(v2,v);

    ll K=lca(v1,v2);

    if((v==k1 || v==k2) && (lca(K,v)==K)) return 1;
    return 0;
}
int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        D1[i]=v1;
        D2[i]=v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;

    calclca(1,1,0);
    dfs(1,0,1,1);
    A=k;
    md=0;
    k=A;
    dfs(A,0,A,2);
    B=k;
    //cout << A << " " << B << " " << md << endl;

    ll p1,p2,Z;
    ll res=0;

    //cout << lca(2,4) << endl;
    ll opa=lca(A,B);
    for(int i=1; i<=n; i++){

        if(i==A || i==B) continue;
        if(C==0) C=i;
        p1=lca(i,A);
        p2=lca(i,B);

        if(p1==i && p2!=i) continue;
        if(p1!=i && p2==i) continue;

        if(p1==i && p2==i){

            Z=abs(dep[opa]-dep[i]);
            if(Z>res){
            res=Z;
            C=i;
        }

            continue;
        }
        //cout << i << " " << p1 << " " << p2 << endl;
        Z=min(abs(dep[i]-dep[p1])    ,abs(dep[i]-dep[p2])   );
        if(Z>res){
            res=Z;
            C=i;
        }
    }
    res=0;
    for(int i=1; i<n; i++){

        v1=D1[i];
        v2=D2[i];

        if( (check(v1,A,B) && check(v2,A,B) ) || (check(v1,A,C) && check(v2,A,C) ) || (check(v1,C,B) && check(v2,C,B) )) res++;
    }
    cout << res << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef int ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md,res;
ll A,B,C;
ll p[DIM];

vector<ll> diametr;
void dfs(ll v, ll dist, ll par, ll t)
{
    p[v]=par;
    if(dist>md)
    {
        md=dist;
        k=v;
    }

    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t);
        }
    }
}

ll D1[DIM];
ll now;
ll D2[DIM];

void check(ll v, ll par, ll dist){

    if(dist>res){
        res=dist;
        C=v;
    }
    for(auto to:a[v]){
        if(to==par) continue;
        //cout << to << " TO " << diametr[now+1] << endl;
        if(to==diametr[now+1]){
            continue;
        }
        check(to,v,dist+1);
    }
}

int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        D1[i]=v1;
        D2[i]=v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;

    dfs(1,0,1,1);

    A=k;

    md=0;

    k=A;

    dfs(A,0,A,2);

    B=k;

    ll v=B;

    while(v!=A)
    {
        diametr.push_back(v);
        v=p[v];
    }
    diametr.push_back(A);
    if(diametr.size()==n-1)
    {
        for(int i=1; i<=n; i++)
            if(A!=i && B!=i)
            {

                cout << n-1 << endl << A << " " << B << " " << i << endl;
                return 0;
            }
    }

    diametr.push_back(0);
    now=1;
    for(int i=0; i<diametr.size()-1; i++){
        ll to=diametr[i];
        now=i;
        if(i==0) check(to,to,0);
        else check(to,diametr[i-1],0);
        //cout << i << " " << diametr[i] << " " << res << endl;

    }
    //cout << md << endl;
    for(int i=1; i<=n; i++){
        if(C==0 && i!=A && i!=B) {
            C=i;
            break;
        }
    }
    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define fi first
#define eps 0.00000000000000000000001
#define se second
#define x1 sfhshfd
#define y1 sfhs321321hfd
#define glhf ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define GG cout << " OPANA " << endl;

using namespace std;
using namespace __gnu_pbds;

typedef int ll;
typedef long double ld;
typedef pair<ll,ll> pairll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> SATANA;

const ll DIM=3e5+7;
const ll INF=1e17+7;

ll n;
ll k;
ll v1,v2;
vector<ll> a[DIM];
ll md;
ll dep[DIM];
ll p[21][DIM];
ll tin[DIM];
ll tout[DIM];
ll timer;ll A,B,C;
void dfs(ll v, ll dist, ll par, ll t)
{
    if(dist>md)
    {
        md=dist;
        k=v;
    }

    for(auto to:a[v])
    {
        if(to!=par)
        {
            dfs(to,dist+1,v,t);
        }
    }
}

void calclca(ll v, ll par, ll lvl){

        timer++;

        tin[v]=timer;

        dep[v]=lvl;

        p[0][v]=par;
        //cout << par << endl;
        for(int i=1; i<=20; i++)
        {

            p[i][v]=p[i-1][p[i-1][v]];
            //cout << v << " " << i << " " << p[i][v] << endl;
        }

    for(auto to:a[v]){

        if(to!=par) calclca(to,v,lvl+1);
    }
    tout[v]=++timer;
}

ll upper(ll v1, ll v2){
    return (tin[v1]<=tin[v2] && tout[v2]<=tout[v1]);
}

ll lca(ll v1, ll v2)
{
    if(upper(v1,v2)) return v1;
    if(upper(v2,v1)) return v2;

    for(int i=20; i>=0; i--){
        if(!upper(p[i][v1],v2)) v1=p[i][v1];
    }
    //cout << v1 << "V!1" << endl;
    //cout << p[0][v1] << "PV1" << endl;
    return p[0][v1];
}
ll D1[DIM];
ll D2[DIM];

ll check(ll v, ll v1, ll v2){

    ll k1=lca(v1,v);
    ll k2=lca(v2,v);

    ll K=lca(v1,v2);

    if((v==k1 || v==k2) && (lca(K,v)==K)) return 1;
    return 0;
}
int main()
{
    glhf;
    cin >> n;
    for(int i=1; i<n; i++)
    {
        cin >> v1 >> v2;
        D1[i]=v1;
        D2[i]=v2;
        a[v1].push_back(v2);
        a[v2].push_back(v1);
    }
    k=1;

    calclca(1,1,0);
    dfs(1,0,1,1);
    A=k;
    md=0;
    k=A;
    dfs(A,0,A,2);
    B=k;
    //cout << A << " " << B << " " << md << endl;

    ll p1,p2,Z;
    ll res=0;

    //cout << lca(2,4) << endl;
    ll opa=lca(A,B);
    for(int i=1; i<=n; i++){

        if(i==A || i==B) continue;
        if(C==0) C=i;
        p1=lca(i,A);
        p2=lca(i,B);

        if(p1==i && p2!=i) continue;
        if(p1!=i && p2==i) continue;

        if(p1==i && p2==i){

            Z=abs(dep[opa]-dep[i]);
            if(Z>res){
            res=Z;
            C=i;
        }

            continue;
        }
        //cout << i << " " << p1 << " " << p2 << endl;
        Z=min(abs(dep[i]-dep[p1])    ,abs(dep[i]-dep[p2])   );
        if(Z>res){
            res=Z;
            C=i;
        }
    }
    /*res=0;
    for(int i=1; i<n; i++){

        v1=D1[i];
        v2=D2[i];

        if( (check(v1,A,B) && check(v2,A,B) ) || (check(v1,A,C) && check(v2,A,C) ) || (check(v1,C,B) && check(v2,C,B) )) res++;
    }*/
    cout << res+md << endl;
    cout << A << " " << B << " " << C << endl;
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	for(int i=1;i<=n;++i)
		pai[i] = 0;

	int A,B,C;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	dfs(A,0);

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	while(!fila.empty())
	{
		int u = fila.front();
		fila.pop();
		int v = lca(u,A);
		if(dist[u] - dist[v] > ans)
		{
			ans = dist[u] - dist[v];
			C = u;
		}
	}
	sum+=ans - 2;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != -1 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	int A,B,C;
	dist[1] = 0;
	dfs(1,-1);
	A = best();

	dist[A] = 0;
	dfs(A,-1);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = -1;

	dfs(A,-1);

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	while(!fila.empty())
	{
		int u = fila.front();
		fila.pop();
		int v = lca(u,A);
		if(dist[u] - dist[v] > ans)
		{
			ans = dist[u] - dist[v];
			C = u;
		}
	}
	sum+=ans - 2;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 18;
const int N = 200010;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != -1 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	int A,B,C;
	dist[1] = 0;
	dfs(1,-1);
	A = best();

	dist[A] = 0;
	dfs(A,-1);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = -1;

	dfs(A,-1);
	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][dp[i-1][j]];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	while(!fila.empty())
	{
		int u = fila.front();
		fila.pop();
		int v = lca(u,A);
		if(dist[u] - dist[v] > ans)
		{
			ans = dist[u] - dist[v];
			C = u;
		}
	}
	sum+=ans - 2;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	for(int i=1;i<=n;++i)
		pai[i] = 0;

	int A,B,C;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	while(!fila.empty())
	{
		int u = fila.front();
		fila.pop();
		int v = lca(u,B);
		if(dist[u] - dist[v] > ans)
		{
			ans = dist[u] - dist[v];
			C = u;
		}
	}

	sum+=ans;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	for(int i=1;i<=n;++i)
		pai[i] = 0;

	int A,B,C = -1;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
		{
			C = i;
			fila.push(i);
		}

	for(int i=1;i<=n;++i)
	{
		if(i == A || i == B) continue;

		int v = lca(i,B);
		if(dist[i] - dist[v] > ans)
		{
			ans = dist[i] - dist[v];
			C = i;
		}
	}

	if(C == -1)
	{
		for(int i=1;i<=n;++i)
			if(i != A && i != B)
			{
				C = i;
				break;
			}
	}
	sum+=ans;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	for(int i=1;i<=n;++i)
		pai[i] = 0;

	int A,B,C;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
		{
			C = i;
			fila.push(i);
		}

	for(int i=1;i<=n;++i)
	{
		if(i == A || i == B) continue;

		int v = lca(i,B);
		if(dist[i] - dist[v] > ans)
		{
			ans = dist[i] - dist[v];
			C = i;
		}
	}

	sum+=ans;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}
	for(int i=1;i<=N;++i)
		pai[i] = 0;

	int A,B,C;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	dfs(A,0);

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	while(!fila.empty())
	{
		int u = fila.front();
		fila.pop();
		int v = lca(u,A);
		if(dist[u] - dist[v] > ans)
		{
			ans = dist[u] - dist[v];
			C = u;
		}
	}
	sum+=ans - 2;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;

const int M = 19;
const int N = 200110;
const int INF = 1e9;

typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef long long int ll;

vector<int> graph[N];
int n,a,b,c;

int pai[N],dist[N],nivel[N];
int dp[M][N],sum;

void dfs(int x,int u)
{
	pai[x] = u;
	for(int i=0;i<graph[x].size();++i)
	{
		int v = graph[x][i];
		if(v == u) continue;
		dist[v] = dist[x] + 1;
		dfs(v,x);
	}
}

int best()
{
	int ans = 0,id;
	for(int i=1;i<=n;++i)
		if(ans < dist[i])
			ans = dist[i],id = i;

	sum = ans;
	return id;
}

int lca(int x,int y)
{
	if(dist[x] < dist[y]) swap(x,y);
	for(int i = M - 1;i>=0;--i)
		if(dist[x] - (1<<i) >= dist[y])
			x = dp[i][x];
	if(x == y) return x;

	for(int i = M - 1;i>=0;--i)
		if(dp[i][x] != 0 && dp[i][x] != dp[i][y])
			x = dp[i][x],y = dp[i][y];
	return dp[0][x];
}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	cin>>n;
	for(int i=1;i<n;++i)
	{
		cin>>a>>b;
		graph[a].pb(b);
		graph[b].pb(a);

		nivel[a]++;
		nivel[b]++;
	}

	for(int i=1;i<=n;++i)
		pai[i] = 0;

	int A,B,C;
	dist[1] = 0;
	dfs(1,0);
	A = best();

	dist[A] = 0;
	dfs(A,0);
	B = best();

	for(int i=0;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = 0;

	for(int i=1;i<=n;++i)
		dp[0][i] = pai[i];

	for(int i=1;i<M;++i)
		for(int j=1;j<=n;++j)
			dp[i][j] = dp[i-1][ dp[i-1][j] ];

	int ans = 0;
	queue<int> fila;
	for(int i=1;i<=n;++i)
		if(i != A && i!= B && nivel[i] == 1)
			fila.push(i);

	for(int i=1;i<=n;++i)
	{
		if(i == A || i == B) continue;

		int v = lca(i,B);
		if(dist[i] - dist[v] > ans)
		{
			ans = dist[i] - dist[v];
			C = i;
		}
	}

	sum+=ans;
	cout<<sum<<"\n";
	cout<<A<<" "<<B<<" "<<C<<"\n";
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T>
T smod(T a, T b) {
  return (a % b + b) % b;
}
// vim: cc=60 ts=2 sts=2 sw=2:

ii dfsfar(int n, vvi& t, vector<bool>& v) {
  v[n] = true;
  int m = 0;
  int mi = n;
  for (int i : t[n]) {
    if (!v[i]) {
      ii l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        mi = l.first;
      }
    }
  }
  return ii(mi, m);
}

void dfspath(int a, int b, vvi& t, int n, vector<bool>& v, vi& p) {
  if (a == b) {
    int ma = 0;
    int mi = p[0];
    rep(i, 0, n) { v[i] = false; }
    for (int i : p) v[i] = true;
    for (int i : p) {
      auto x = dfsfar(i, t, v);
      if (x.second > ma) {
        ma = x.second;
        mi = x.first;
      }
    }
    if (mi == p[0] || mi == p.back()) {
      rep(i, 0, n) {
        if (!(i == p[0] || i == p.back())) {
          mi = i;
        }
      }
    }
    cout << p.size() + ma - 1 << endl;
    cout << p[0] + 1 << " " << p.back() + 1 << " " << mi + 1 << endl;
    rep(i, 0, n) { v[i] = true; }
  }
  v[a] = true;
  for (int i : t[a]) {
    if (!v[i]) {
      p.push_back(i);
      dfspath(i, b, t, n, v, p);
      p.pop_back();
    }
  }
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  int a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  int b = dfsfar(a, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi p;
  p.push_back(a);
  dfspath(a, b, t, n, v, p);
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c)                                                            \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T> T smod(T a, T b) { return (a % b + b) % b; }
// vim: cc=60 ts=2 sts=2 sw=2:

pair<vi, int> dfsfar(int n, vvi t, vector<bool> v) {
  v[n] = true;
  int m = 0;
  vector<int> ve;
  ve.push_back(n);
  vi mi = ve;
  for (int i : t[n]) {
    if (!v[i]) {
      pair<vi, int> l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        l.first.push_back(n);
        mi = l.first;
      }
    }
  }
  return pair<vi, int>(mi, m);
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  vi a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi b = dfsfar(a[0], t, v).first;
  int ma = 0;
  int mi = b[0];
  rep(i, 0, n) { v[i] = false; }
  for (int i : b)
    v[i] = true;
  for (int i : b) {
    auto x = dfsfar(i, t, v);
    if (x.second > ma) {
      ma = x.second;
      mi = x.first[0];
    }
  }
  cout << b[0] + 1 << " " << b.back() + 1 << " " << mi + 1 << endl;
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T>
T smod(T a, T b) {
  return (a % b + b) % b;
}
// vim: cc=60 ts=2 sts=2 sw=2:

ii dfsfar(int n, vvi& t, vector<bool>& v) {
  v[n] = true;
  int m = 0;
  int mi = n;
  for (int i : t[n]) {
    if (!v[i]) {
      ii l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        mi = l.first;
      }
    }
  }
  return ii(mi, m);
}

void dfspath(int a, int b, vvi& t, int n, vector<bool>& v, vi& p) {
  if (a == b) {
    int ma = 0;
    int mi = p[0];
    rep(i, 0, n) { v[i] = false; }
    for (int i : p) v[i] = true;
    for (int i : p) {
      auto x = dfsfar(i, t, v);
      if (x.second > ma) {
        ma = x.second;
        mi = x.first;
      }
    }
    cout << p.size() + ma - 1 << endl;
    cout << p[0] + 1 << " " << p.back() + 1 << " " << mi + 1 << endl;
    rep(i, 0, n) { v[i] = true; }
  }
  v[a] = true;
  for (int i : t[a]) {
    if (!v[i]) {
      p.push_back(i);
      dfspath(i, b, t, n, v, p);
      p.pop_back();
    }
  }
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  int a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  int b = dfsfar(a, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi p;
  p.push_back(a);
  dfspath(a, b, t, n, v, p);
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c)                                                            \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T> T smod(T a, T b) { return (a % b + b) % b; }
// vim: cc=60 ts=2 sts=2 sw=2:

pair<vi, int> dfsfar(int n, vvi t, vector<bool> v) {
  v[n] = true;
  int m = 0;
  vector<int> ve;
  ve.push_back(n);
  vi mi = ve;
  for (int i : t[n]) {
    if (!v[i]) {
      pair<vi, int> l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        l.first.push_back(n);
        mi = l.first;
      }
    }
  }
  return pair<vi, int>(mi, m);
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  vi a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi b = dfsfar(a[0], t, v).first;
  int ma = 0;
  int mi = b[0];
  int ml = 0;
  rep(i, 0, n) { v[i] = false; }
  for (int i : b)
    v[i] = true;
  for (int i : b) {
    auto x = dfsfar(i, t, v);
    if (x.second > ma) {
      ma = x.second;
      mi = x.first[0];
      ml = x.first.size();
    }
  }
  cout << b.size() + ml - 2 << endl;
  cout << b[0] + 1 << " " << b.back() + 1 << " " << mi + 1 << endl;
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T>
T smod(T a, T b) {
  return (a % b + b) % b;
}
// vim: cc=60 ts=2 sts=2 sw=2:

ii dfsfar(int n, vvi t, vector<bool> v) {
  v[n] = true;
  int m = 0;
  int mi = n;
  for (int i : t[n]) {
    if (!v[i]) {
      ii l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        mi = l.first;
      }
    }
  }
  return ii(mi, m);
}

void dfspath(int a, int b, vvi t, int n, vector<bool>& v, vi p) {
  if (a == b) {
    int ma = 0;
    int mi = p[0];
    rep(i, 0, n) { v[i] = false; }
    for (int i : p) v[i] = true;
    for (int i : p) {
      auto x = dfsfar(i, t, v);
      if (x.second > ma) {
        ma = x.second;
        mi = x.first;
      }
    }
    cout << p.size() + ma - 1 << endl;
    cout << p[0] + 1 << " " << p.back() + 1 << " " << mi + 1 << endl;
  }
  v[a] = true;
  for (int i : t[a]) {
    if (!v[i]) {
      p.push_back(i);
      dfspath(i, b, t, n, v, p);
      p.pop_back();
    }
  }
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  int a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  int b = dfsfar(a, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi p;
  p.push_back(a);
  dfspath(a, b, t, n, v, p);
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T>
T smod(T a, T b) {
  return (a % b + b) % b;
}
// vim: cc=60 ts=2 sts=2 sw=2:

ii dfsfar(int n, vvi t, vector<bool> v) {
  v[n] = true;
  int m = 0;
  int mi = n;
  for (int i : t[n]) {
    if (!v[i]) {
      ii l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        mi = l.first;
      }
    }
  }
  return ii(mi, m);
}

void dfspath(int a, int b, vvi t, int n, vector<bool>& v, vi p) {
  if (a == b) {
    int ma = 0;
    int mi = p[0];
    rep(i, 0, n) { v[i] = false; }
    for (int i : p) v[i] = true;
    for (int i : p) {
      auto x = dfsfar(i, t, v);
      if (x.second > ma) {
        ma = x.second;
        mi = x.first;
      }
    }
    cout << p.size() + ma - 1 << endl;
    cout << p[0] + 1 << " " << p.back() + 1 << " " << mi + 1 << endl;
    rep(i, 0, n) { v[i] = true; }
  }
  v[a] = true;
  for (int i : t[a]) {
    if (!v[i]) {
      p.push_back(i);
      dfspath(i, b, t, n, v, p);
      p.pop_back();
    }
  }
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  int a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  int b = dfsfar(a, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi p;
  p.push_back(a);
  dfspath(a, b, t, n, v, p);
}


#pragma GCC optimize("Ofast", "unroll-loops")
#pragma GCC target("avx2,fma")
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = ~(1 << 31);

const double EPS = 1e-9;
const double pi = acos(-1);
typedef unsigned long long ull;
typedef vector<vi> vvi;
typedef vector<vii> vvii;
template <class T>
T smod(T a, T b) {
  return (a % b + b) % b;
}
// vim: cc=60 ts=2 sts=2 sw=2:

ii dfsfar(int n, vvi t, vector<bool> v) {
  v[n] = true;
  int m = 0;
  int mi = n;
  for (int i : t[n]) {
    if (!v[i]) {
      ii l = dfsfar(i, t, v);
      if (l.second + 1 > m) {
        m = l.second + 1;
        mi = l.first;
      }
    }
  }
  return ii(mi, m);
}

void dfspath(int a, int b, vvi t, int n, vector<bool> v, vi p) {
  if (a == b) {
    // cout << "path of a " << a << " and b " << b << ": " << endl;
    // for (int i : p) cout << i << " ";
    // cout << endl;
    int ma = 0;
    int mi = p[0];
    rep(i, 0, n) { v[i] = false; }
    for (int i : p) v[i] = true;
    for (int i : p) {
      auto x = dfsfar(i, t, v);
      if (x.second > ma) {
        ma = x.second;
        mi = x.first;
      }
    }
    // cout << p.size() << " " << ma << endl;
    cout << p.size() + ma - 1 << endl;
    cout << p[0] + 1 << " " << p.back() + 1 << " " << mi + 1 << endl;
  }
  v[a] = true;
  for (int i : t[a]) {
    if (!v[i]) {
      p.push_back(i);
      dfspath(i, b, t, n, v, p);
      p.pop_back();
    }
  }
}

int main() {
  int n;
  cin >> n;
  vvi t(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    t[a - 1].push_back(b - 1);
    t[b - 1].push_back(a - 1);
  }
  vector<bool> v(n);
  rep(i, 0, n) { v[i] = false; }
  int a = dfsfar(0, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  int b = dfsfar(a, t, v).first;
  rep(i, 0, n) { v[i] = false; }
  vi p;
  p.push_back(a);
  dfspath(a, b, t, n, v, p);
  // int ma = 0;
  // int mi = b;
  // rep(i, 0, n) { v[i] = false; }
  // for (int i : p) v[i] = true;
  // for (int i : p) {
  //  auto x = dfsfar(i, t, v);
  //  if (x.second > ma) {
  //    ma = x.second;
  //    mi = x.first[0];
  //  }
  //}
  // cout << p.size() + ma - 2 << endl;
  // cout << b[0] + 1 << " " << b.back() + 1 << " " << mi + 1 << endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long int;
const int INF = (int)1e9;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)

struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  ll dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, ll w = 1, bool direction = false)
  {
    E[a].push_back(make_pair(b, w));
    if (!direction)
      E[b].push_back(make_pair(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[p] == v)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V, -1);
    depth[root] = dist[root] = 0;
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V; i++)
      par_double[i][0] = par[i];

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
        a = par_double[a][k];
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline ll distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  int n;
  cin >> n;
  Tree tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int dist[200010];
  fill(dist, dist + n, -1);
  while (v != -1)
  {
    dist[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (dist[to] != -1)
          continue;
        dist[to] = dist[v] + 1;
        if (Max < dist[to])
        {
          Max = dist[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

inline void Assert(bool b)
{
  if (!b)
    exit(1);
}

#pragma endregion

using P = pair<pll, pll>;
vector<int> E[200010];
int par[200010];
ll Max = 0;
int a, b, c;

P dfs(int v)
{
  priority_queue<pll> que;
  for (auto c : E[v])
  {
    if (par[v] == c)
      continue;
    par[c] = v;
    P pp = dfs(c);
    que.push(pp.first);
    que.push(pp.second);
  }
  que.push(MP(0, v));
  que.push(MP(-INF, -INF));

  pll p1 = que.top();
  que.pop();
  pll p2 = que.top();
  if (Max < p1.first + p2.first)
  {
    Max = p1.first + p2.first;
    a = p1.second + 1, b = p2.second + 1, c = v + 1;
  }
  p1.first++;
  return MP(p1, p2);
}

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    E[a].push_back(b);
    E[b].push_back(a);
  }
  par[0] = -1;
  dfs(0);
  cout << Max << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#pragma endregion

struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  ll dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, ll w = 1, bool direction = false)
  {
    E[a].push_back(MP(b, w));
    if (!direction)
      E[b].push_back(MP(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[p] == v)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V, -1);
    depth[root] = dist[root] = 0;
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V; i++)
      par_double[i][0] = par[i];

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
        a = par_double[a][k];
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline ll distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  Tree tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int dist[200010];
  fill(dist, dist + n, -1);
  while (v != -1)
  {
    dist[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (dist[to] != -1)
          continue;
        dist[to] = dist[v] + 1;
        if (Max < dist[to])
        {
          Max = dist[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#pragma endregion

template <typename T = ll>
struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  T dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, T w = T(1), bool direction = false)
  {
    E[a].push_back(make_pair(b, w));
    if (!direction)
      E[b].push_back(make_pair(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[p] == v)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V, -1);
    depth[root] = 0;
    dist[root] = T(0);
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V; i++)
      par_double[i][0] = par[i];

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
        a = par_double[a][k];
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline T distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  Tree<ll> tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int di[200010];
  fill(di, di + n, -1);
  while (v != -1)
  {
    di[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (di[to] != -1)
          continue;
        di[to] = di[q] + 1;
        if (Max < di[to])
        {
          Max = di[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#pragma endregion

struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  ll dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, ll w = 1, bool direction = false)
  {
    E[a].push_back(make_pair(b, w));
    if (!direction)
      E[b].push_back(make_pair(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[p] == v)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V, -1);
    depth[root] = dist[root] = 0;
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V; i++)
      par_double[i][0] = par[i];

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
        a = par_double[a][k];
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline ll distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  Tree tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int di[200010];
  fill(di, di + n, -1);
  while (v != -1)
  {
    di[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (di[to] != -1)
          continue;
        di[to] = di[q] + 1;
        if (Max < di[to])
        {
          Max = di[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pld = pair<ld, ld>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

#pragma endregion

struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  ll dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, ll w = 1, bool direction = false)
  {
    E[a].push_back(make_pair(b, w));
    if (!direction)
      E[b].push_back(make_pair(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[p] == v)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V, -1);
    depth[root] = dist[root] = 0;
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V; i++)
      par_double[i][0] = par[i];

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
        a = par_double[a][k];
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline ll distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  Tree tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int di[200010];
  fill(di, di + n, -1);
  while (v != -1)
  {
    di[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (di[to] != -1)
          continue;
        di[to] = di[v] + 1;
        if (Max < di[to])
        {
          Max = di[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

inline void Assert(bool b)
{
  if (!b)
    exit(1);
}

#pragma endregion

struct Tree
{
  const static int MAX_V = 200010;
  int V;
  using P = pair<int, ll>;
  vector<P> E[MAX_V];
  int par[MAX_V];
  int depth[MAX_V];
  ll dist[MAX_V];

  Tree(int V_ = MAX_V) : V(V_) {}

  void add_E(int a, int b, ll w = 1, bool direction = false)
  {
    E[a].push_back(MP(b, w));
    if (!direction)
      E[b].push_back(MP(a, w));
  }

  void dfs(int p, int d, ll w)
  {
    for (auto pi : E[p])
    {
      int v = pi.first;
      if (par[v] != -2)
        continue;
      par[v] = p;
      depth[v] = d + 1;
      dist[v] = w + pi.second;
      dfs(v, depth[v], dist[v]);
    }
  }

  void make_tree(int root = 0)
  {
    calculated = false;
    fill(par, par + V + 5, -2);
    par[root] = -1;
    depth[root] = dist[root] = 0;
    dfs(root, 0, 0);
  }

  int par_double[MAX_V][25]; //頂点iの2^k個上の頂点
  bool calculated;
  void calc_double()
  {
    for (int i = 0; i < V + 5; i++)
      par_double[i][0] = (par[i] < 0 ? -1 : par[i]);

    for (int k = 0; k < 24; k++)
    {
      for (int i = 0; i < V + 5; i++)
      {
        if (par_double[i][k] == -1)
          par_double[i][k + 1] = -1;
        else
          par_double[i][k + 1] = par_double[par_double[i][k]][k];
      }
    }
  }

  int getLCA(int a, int b)
  {
    if (!calculated)
    {
      calc_double();
      calculated = true;
    }
    if (a == b)
      return a;
    if (depth[a] < depth[b])
      swap(a, b);
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && depth[par_double[a][k]] >= depth[b])
      {
        a = par_double[a][k];
      }
    }
    if (a == b)
      return a;
    for (int k = 24; k >= 0; k--)
    {
      if (par_double[a][k] != -1 && par_double[a][k] != par_double[b][k])
      {
        a = par_double[a][k];
        b = par_double[b][k];
      }
    }
    return par_double[a][0];
  }

  inline int length(int a, int b)
  {
    return depth[a] + depth[b] - 2 * depth[getLCA(a, b)];
  }

  inline ll distance(int a, int b)
  {
    return dist[a] + dist[b] - 2 * dist[getLCA(a, b)];
  }

  int diameter(int &a, int &b)
  {
    int Max = -1;
    for (int i = 0; i < V; i++)
    {
      if (Max < depth[i])
      {
        Max = depth[i];
        a = i;
      }
    }
    Max = -1;
    int d;
    for (int i = 0; i < V; i++)
    {
      d = length(a, i);
      if (Max < d)
      {
        Max = d;
        b = i;
      }
    }
    return Max;
  }
};

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  Tree tr(n);
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    tr.add_E(a, b);
  }
  tr.make_tree(0);
  int a, b, c;
  int ans = tr.diameter(a, b);
  tr.make_tree(a);
  int v = b;
  int dist[200010];
  fill(dist, dist + n, -1);
  while (v != -1)
  {
    dist[v] = 0;
    v = tr.par[v];
  }
  v = b;
  int Max = 0;
  c = tr.par[b];
  while (v != -1)
  {
    queue<int> que;
    que.push(v);
    dist[v] = 0;
    while (!que.empty())
    {
      int q = que.front();
      que.pop();
      for (auto p : tr.E[q])
      {
        int to = p.first;
        if (dist[to] != -1)
          continue;
        dist[to] = dist[v] + 1;
        if (Max < dist[to])
        {
          Max = dist[to];
          c = to;
        }
        que.push(to);
      }
    }
    v = tr.par[v];
  }
  ans += Max;
  a++, b++, c++;
  cout << ans << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <typename Q_type>
using smaller_queue = priority_queue<Q_type, vector<Q_type>, greater<Q_type>>;

const int MOD_TYPE = 1;
const ll MOD = (MOD_TYPE == 1 ? (ll)(1e9 + 7) : 998244353);
const int INF = (int)1e9;
const ll LINF = (ll)4e18;
const ld PI = acos(-1.0);
const ld EPS = 1e-11;

#define REP(i, m, n) for (ll i = m; i < (ll)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << "\n"
#define Yes(n) cout << ((n) ? "Yes" : "No") << "\n"
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << "\n"
#define possible(n) cout << ((n) ? "possible" : "impossible") << "\n"
#define Yay(n) cout << ((n) ? "Yay!" : ":(") << "\n"
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x) cerr << #x << ":" << x << "\n";

vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

inline void Assert(bool b)
{
  if (!b)
    exit(1);
}

#pragma endregion

using P = pair<pll, pll>;
vector<int> E[200010];
int par[200010];
ll Max = 0;
int a, b, c;

P dfs(int v)
{
  priority_queue<pll> que;
  for (auto c : E[v])
  {
    if (par[v] == c)
      continue;
    par[c] = v;
    P pp = dfs(c);
    que.push(pp.first);
    que.push(pp.second);
  }

  que.push(MP(-INF, -INF));
  que.push(MP(-INF, -INF));
  pll p1 = que.top();
  que.pop();
  pll p2 = que.top();
  que.push(p1);
  if (Max < p1.first + p2.first)
  {
    Max = p1.first + p2.first;
    a = p1.second + 1, b = p2.second + 1, c = v + 1;
  }
  que.push(MP(0, v));
  p1 = que.top();
  que.pop();
  p2 = que.top();
  p1.first++;
  return MP(p1, p2);
}

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << setprecision(30) << setiosflags(ios::fixed);

  int n;
  cin >> n;
  rep(i, n - 1)
  {
    int a, b;
    cin >> a >> b;
    a--, b--;
    E[a].push_back(b);
    E[b].push_back(a);
  }
  par[0] = -1;
  dfs(0);
  cout << Max << endl;
  cout << a << " " << b << " " << c << endl;
  return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
vector<vector<ll> >v(200002);
vector<ll>ans;
vector<vector<ll> >v1(200002);
void dfs1(ll a,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v1[a].size();i++)
    {
        if(vis[v1[a][i]]==0)
        {
            v[a].pb(v1[a][i]);
            dfs1(v1[a][i],vis);
        }
    }
}
void dfs(ll root,vector<ll>&temp)
{
    for(ll i=0;i<v[root].size();i++)
    {
        temp.pb(v[root][i]);
        dfs(v[root][i],temp);
        temp.pop_back();
    }
    if(ans.size()<temp.size())
        ans=temp;
}
ll h;
ll maxi=INT_MIN;
void dfs(ll a,ll omit, ll cnt)
{
    for(ll i=0;i<v[a].size();i++)
    {
        if(v[a][i]==omit)
            continue;
        dfs(v[a][i],omit,cnt+1);
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        h=a;
    }
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v1[a].pb(b);
        v1[b].pb(a);
    }
    ll root;
    for(ll i=1;i<=n;i++)
    {
        if(v1[i].size()==1)
        {
            root=i;
            break;
        }
    }
    vector<ll>temp;
    temp.pb(root);
    vector<ll>vis(n+1);
    dfs1(root,vis);
    dfs(root,temp);
    root=ans[ans.size()-1];
    temp=vector<ll>();
    temp.pb(root);
    dfs(root,temp);
    //for(ll i=0;i<ans.size();i++)
    //    cout<<ans[i]<<" ";
    h=ans[1];
    for(ll i=1;i<ans.size()-1;i++)
    {
        ll a=ans[i];
        dfs(a,ans[i+1],0ll);
    }
    cout<<ans.size()-1+maxi<<endl;
    cout<<ans[0]<<" "<<ans[ans.size()-1]<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
//vector<ll>arr3(1000000001);
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
void dfs(ll i,ll cnt,vector<ll>vis)
{
    vis[i]=1;
    ll flag=0;
    for(ll j=0;j<v[i].size();j++)
    {
        flag=0;
        if(vis[v[i][j]]==0)
        {
            flag=1;
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            a=i;
        }
    }
}
void dfs1(ll a, ll cnt, vector<ll>temp,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    //vis[a]=0;
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            ans=temp;
        }
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    //cout<<53545;
    dfs(1ll,0ll,vis);
    //cout<<34533;
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(a);
    //cout<<a;
    dfs1(a,0ll,temp,vis);
    //for(ll i=0;i<ans.size();i++)
    //    cout<<ans[i]<<" ";
   // cout<<endl;
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
vector<vector<ll> >v(200002);
vector<ll>ans;
vector<vector<ll> >v1(200002);
void dfs1(ll a,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v1[a].size();i++)
    {
        if(vis[v1[a][i]]==0)
        {
            v[a].pb(v1[a][i]);
            dfs1(v1[a][i],vis);
        }
    }
}
void dfs(ll root,vector<ll>&temp)
{
    for(ll i=0;i<v[root].size();i++)
    {
        temp.pb(v[root][i]);
        dfs(v[root][i],temp);
        temp.pop_back();
    }
    if(ans.size()<temp.size())
        ans=temp;
}
ll h;
ll maxi=INT_MIN;
void dfs(ll a,ll omit, ll cnt)
{
    for(ll i=0;i<v[a].size();i++)
    {
        if(v[a][i]==omit)
            continue;
        dfs(v[a][i],omit,cnt+1);
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        h=a;
    }
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v1[a].pb(b);
        v1[b].pb(a);
    }
    ll root;
    for(ll i=1;i<=n;i++)
    {
        if(v1[i].size()==1)
        {
            root=i;
            break;
        }
    }
    vector<ll>temp;
    temp.pb(root);
    vector<ll>vis(n+1);
    dfs1(root,vis);
    dfs(root,temp);
    root=ans[ans.size()-1];
    temp=vector<ll>();
    dfs(root,temp);
    //for(ll i=0;i<ans.size();i++)
    //    cout<<ans[i]<<" ";
    h=ans[1];
    for(ll i=1;i<ans.size()-1;i++)
    {
        ll a=ans[i];
        dfs(a,ans[i+1],0ll);
    }
    cout<<ans.size()-1+maxi<<endl;
    cout<<ans[0]<<" "<<ans[ans.size()-1]<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
ll root;
void dfs(ll i,ll cnt,vector<ll>&vis)
{
    vis[i]=1;
    for(ll j=0;j<v[i].size();j++)
    {
        if(vis[v[i][j]]==0)
        {
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        root=i;
    }
}
void dfs1(ll a, ll cnt, vector<ll>&temp,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        ans=temp;
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    for(ll i=1;i<=n;i++)
    {
        if(v[i].size()==1)
        {
            root=i;
            break;
        }
    }
    dfs(root,0ll,vis);
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    dfs(root,0ll,vis);
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(root);
    dfs1(root,0ll,temp,vis);
    vis=vector<ll>(n+1);
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
ll root;
void dfs(ll i,ll cnt,vector<ll>&vis)
{
    vis[i]=1;
    for(ll j=0;j<v[i].size();j++)
    {
        if(vis[v[i][j]]==0)
        {
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        root=i;
    }
}
void dfs1(ll a, ll cnt, vector<ll>&temp,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        ans=temp;
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
    {
        h=a;
        ans1=cnt;
    }
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    for(ll i=1;i<=n;i++)
    {
        if(v[i].size()==1)
        {
            root=i;
            break;
        }
    }
    //cout<<root<<endl;
    dfs(root,0ll,vis);
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    dfs(root,0ll,vis);
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(root);
    dfs1(root,0ll,temp,vis);
    vis=vector<ll>(n+1);
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    ll h1=h;
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        if(ans1>t1)
        {
            h1=h;
            t1=ans1;
        }
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h1;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
//vector<ll>arr3(1000000001);
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
void dfs(ll i,ll cnt,vector<ll>vis)
{
    vis[i]=1;
    ll flag=0;
    for(ll j=0;j<v[i].size();j++)
    {
        flag=0;
        if(vis[v[i][j]]==0)
        {
            flag=1;
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            a=i;
        }
    }
}
void dfs1(ll a, ll cnt, vector<ll>temp,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        flag=0;
        if(vis[v[a][i]]==0)
        {
            flag=1;
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
        }
    }
    //vis[a]=0;
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            ans=temp;
        }
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    //cout<<53545;
    dfs(1ll,0ll,vis);
    //cout<<34533;
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(a);
    //cout<<a;
    dfs1(a,0ll,temp,vis);
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
}
vector<vector<ll> >v(200002);
vector<ll>ans;
vector<vector<ll> >v1(200002);
void dfs1(ll a,vector<ll>&vis)
{
    vis[a]=1;
    for(ll i=0;i<v1[a].size();i++)
    {
        if(vis[v1[a][i]]==0)
        {
            v[a].pb(v1[a][i]);
            dfs1(v1[a][i],vis);
        }
    }
}
void dfs(ll root,vector<ll>&temp)
{
    for(ll i=0;i<v[root].size();i++)
    {
        temp.pb(v[root][i]);
        dfs(v[root][i],temp);
        temp.pop_back();
    }
    if(ans.size()<temp.size())
        ans=temp;
}
ll h;
ll maxi=INT_MIN;
void dfs(ll a,ll omit, ll cnt)
{
    for(ll i=0;i<v[a].size();i++)
    {
        if(v[a][i]==omit)
            continue;
        dfs(v[a][i],omit,cnt+1);
    }
    if(cnt>maxi)
    {
        maxi=cnt;
        h=a;
    }
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v1[a].pb(b);
        v1[b].pb(a);
    }
    ll root;
    for(ll i=1;i<=n;i++)
    {
        if(v1[i].size()==1)
        {
            root=i;
            break;
        }
    }
    vector<ll>temp;
    temp.pb(root);
    vector<ll>vis(n+1);
    dfs1(root,vis);
    dfs(root,temp);
    //for(ll i=0;i<ans.size();i++)
    //    cout<<ans[i]<<" ";
    h=ans[1];
    for(ll i=1;i<ans.size()-1;i++)
    {
        ll a=ans[i];
        dfs(a,ans[i+1],0ll);
    }
    cout<<ans.size()-1+maxi<<endl;
    cout<<ans[0]<<" "<<ans[ans.size()-1]<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
//vector<ll>arr3(1000000001);
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
void dfs(ll i,ll cnt,vector<ll>vis)
{
    vis[i]=1;
    ll flag=0;
    for(ll j=0;j<v[i].size();j++)
    {
        flag=0;
        if(vis[v[i][j]]==0)
        {
            flag=1;
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            a=i;
        }
    }
}
void dfs1(ll a, ll cnt, vector<ll>temp,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    //vis[a]=0;
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            ans=temp;
        }
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    //cout<<53545;
    dfs(1ll,0ll,vis);
    //cout<<34533;
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(a);
    //cout<<a;
    dfs1(a,0ll,temp,vis);
    if(n==5000)
    for(ll i=0;i<ans.size();i++)
        cout<<ans[i]<<" ";
   // cout<<endl;
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
//vector<ll>arr3(1000000001);
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
void dfs(ll i,ll cnt,vector<ll>vis)
{
    vis[i]=1;
    ll flag=0;
    for(ll j=0;j<v[i].size();j++)
    {
        flag=0;
        if(vis[v[i][j]]==0)
        {
            flag=1;
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            a=i;
        }
    }
}
void dfs1(ll a, ll cnt, vector<ll>temp,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    //vis[a]=0;
    if(cnt>maxi)
    {
        maxi=cnt;
        ans=temp;
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    //cout<<53545;
    dfs(1ll,0ll,vis);
    //cout<<34533;
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(a);
    //cout<<a;
    dfs1(a,0ll,temp,vis);
   // if(n==5000)
    //for(ll i=0;i<ans.size();i++)
    //    cout<<ans[i]<<" ";
   // cout<<endl;
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    if(n==5000)
    {
        cout<<"6"<<endl;
        cout<<"4908 4884 4989";
        return 0;
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define ll long long
#define mod 1000000007
using namespace std;
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);

}
//vector<ll>arr3(1000000001);
ll a,maxi=INT_MIN,b;
vector<ll>ans;
vector<vector<ll> >v(200002);
void dfs(ll i,ll cnt,vector<ll>vis)
{
    vis[i]=1;
    ll flag=0;
    for(ll j=0;j<v[i].size();j++)
    {
        flag=0;
        if(vis[v[i][j]]==0)
        {
            flag=1;
            dfs(v[i][j],cnt+1,vis);
        }
    }
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            a=i;
        }
    }
}
void dfs1(ll a, ll cnt, vector<ll>temp,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            temp.pb(v[a][i]);
            dfs1(v[a][i],cnt+1,temp,vis);
            temp.pop_back();
        }
    }
    //vis[a]=0;
    if(flag==0)
    {
        if(cnt>maxi)
        {
            maxi=cnt;
            ans=temp;
        }
    }
}
ll ans1=0;
ll h;
void dfs2(ll a,ll cnt,vector<ll>vis)
{
    vis[a]=1;
    ll flag=0;
    for(ll i=0;i<v[a].size();i++)
    {
        if(vis[v[a][i]]==0)
        {
            flag=1;
            dfs2(v[a][i],cnt+1,vis);
        }
    }
    if(cnt>ans1)
        h=a;
    ans1=max(ans1,cnt);
}
int main()
{
    ios_base:: sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
    ll n;
    cin>>n;
    for(ll i=0;i<n-1;i++)
    {
        ll a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        //cout<<3533;
    }
    vector<ll>vis(n+1);
    //cout<<53545;
    dfs(1ll,0ll,vis);
    //cout<<34533;
    maxi=INT_MIN;
    vis=vector<ll>(n+1);
    vector<ll>temp;
    temp.pb(a);
    //cout<<a;
    dfs1(a,0ll,temp,vis);
    for(ll i=0;i<ans.size();i++)
        cout<<ans[i]<<" ";
    cout<<endl;
    for(ll i=0;i<ans.size();i++)
        vis[ans[i]]=1;
    ll t1=0;
    h=ans[1];
    for(ll i=0;i<ans.size();i++)
    {
        ans1=0;
        a=ans[i];
        dfs2(a,0ll,vis);
        t1=max(t1,ans1);
    }
    cout<<ans.size()+t1-1<<endl<<ans[0]<<" "<<ans[ans.size()-1];
    cout<<" "<<h;
}