#include <iostream>
#include <vector>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <functional>
#include <string>
#include <queue>
#include <cmath>
#include <iomanip>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <random>
#include <unordered_map>
#include <unordered_set>
#include <numeric>
#define ll long long
#define fr(i,k,N) for(decltype(N+k) i=k; i<N;i++)
#define rep(i,N) for(decltype(N) i=0; i<N;i++)
#define ALL(v) v.begin(),v.end()
using namespace std;
template <class X> void pr(X test){cout<<test<<endl;}
template <class X> void prr(X test){for(auto it:test){cout<<it<<endl;}}
template <class X> void prrr(X test){int f=0;for(auto it:test){cout<<(f++!=0?" ":"")<<it;}cout<<endl;}
template<typename X>
istream&operator>>(istream&i,vector<X>&v){for(X&x:v)i>>x;return i;}

class UF { // union find from https://github.com/kartikkukreja/blog-codes (MIT)
    // [usage]
    // auto uf = new UF(n);
    // uf->merge(l, r); // 0 <= l, r <= n-1
    // ...
public:
    int *id; // inner id
    int cnt; // number of all vartices
    int *sz; // sz[i] means size of i's set
    UF(int N)   {
        cnt = N;
        id = new int[N];
        sz = new int[N];
        for(int i=0; i<N; i++) {
            id[i] = i;
            sz[i] = 1;
        }
    }
    ~UF() {
        delete [] id;
        delete [] sz;
    }
    int find(int p) {
        int root = p;
        while (root != id[root]) root = id[root];
        while (p != root) {
            int newp = id[p];
            id[p] = root;
            p = newp;
        }
        return root;
    }
    void merge(int x, int y) {
        int i = find(x);
        int j = find(y);
        if (i == j) return;
        
        if (sz[i] < sz[j]) {
            id[i] = j;
            sz[j] += sz[i];
        } else {
            id[j] = i;
            sz[i] += sz[j];
        }
        cnt--;
    }
    bool connected(int x, int y) {
        return find(x) == find(y);
    }
    int count() {
        return cnt;
    }
};

// return 約数unordered_set 1 <= x <= n
auto divv = [](auto n) {
  unordered_set<decltype(n)> v;
  for(decltype(n) i = 1; i*i <= n; i++) {
    if(n%i == 0) {
      v.insert(i);
      if(i*i != n) v.insert(n/i);
    }
  }
  return v;
};

// check prime (and n>=2) or not
auto isPrime = [](auto n){
  if(n <= 1) return false;
  for(decltype(n) i = 2; i <= sqrt(n); ++i) {
      if(n % i == 0) {
          return false;
      }
  }
  return true;
};

int main() {
    
    ll n;
    cin>>n;
    ll u,v;
    cin>>u>>v;
    unordered_map<ll,vector<ll>> g;
    rep(i, n-1){
        ll a, b;
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    unordered_map<ll,ll> warn;
    {
        queue<pair<ll, queue<ll>>> q;
        queue<ll> t ;
        t.push(v);
        q.push({v,t});
        unordered_set<ll> visited;
        visited.insert(v);
        ll ans = 0;

        ll end = true;
        queue<ll> real_back;
        while(end && !q.empty()){
            auto xx = q.front();
            auto x = xx.first;
            auto back = xx.second;

            q.pop();
            for(auto jt:g[x]){
                if(jt == u){
                    back.push(jt);
                    end = false;
                    real_back = back;
                    break;
                }
                if(visited.count(jt) ==0){
                    visited.insert(jt);
                    auto tmp = back;
                    tmp.push(jt);
                    q.push({jt, tmp});
                }
            }
        }
        ll sz = 0;
        while(!real_back.empty()){
            auto y = real_back.front();
            warn[y]=sz;
            real_back.pop();
            sz++;
        }
    }
    {
        queue<pair<ll,ll>> q;
        q.push({u, (ll)0});
        unordered_set<ll> visited;
        visited.insert(u);
        ll ans = 0;
        while(!q.empty()){
            auto xx = q.front();
            auto x = xx.first;
            auto score = xx.second;
            q.pop();
            bool flg = true;
            for(auto jt:g[x]){
                if(visited.count(jt) ==0){
                    if(warn.count(jt) ==1){
                        auto w = warn[jt];
                        if(w > score) { // ok?
                            visited.insert(jt);
                            auto ss =score+1;
                            ss -= (warn.size() -w-1);
                            q.push({jt, ss}); // ?
                            flg = false;
                        }else{// ng?
                            visited.insert(jt);
                        }
                    }else{
                        visited.insert(jt);

                        q.push({jt, score+1});

                        flg=false;
                    }
                }
            }
            if(flg){
                ans = max(ans, score);
            }
        }
        auto aoki = warn.size()-1;
        pr(ans+aoki-2);
        // pr(aoki);
    }




 

}
