// #pragma GCC optimize("Ofast","unroll-loops")
// #pragma GCC push_options
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #include<bits/stdc++.h>
// #include <xmmintrin.h>
// #include <immintrin.h>
// using namespace::std;
// __attribute__((constructor))void init(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/priority_queue.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// template<typename T>using pbds=__gnu_pbds::tree<T,__gnu_pbds::null_type,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
// template<typename T>using pbds_map=__gnu_pbds::tree<T,T,less<T>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update>;
// template<typename T,typename E>using hash_map=__gnu_pbds::gp_hash_table<T,E>;
// template<typename T>using pqueue =__gnu_pbds::priority_queue<T, less<T>,__gnu_pbds::rc_binomial_heap_tag>;
// typedef long long lint;
// #define INF (1LL<<60)
// #define IINF (1<<30)
// #define EPS (1e-10)
// typedef vector<lint> vec;
// typedef vector<vector<lint>> mat;
// template<typename T>inline void numout(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i<INF/2?i:"INF";f=1;}cout<<endl;}
// template<typename T>inline void numout2(T t){for(auto i:t)numout(i);}
// template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
// template<typename T>inline void output2(T t){for(auto i:t)output(i);}
// template<typename T>inline void _output(T t){bool f=0;for(int i=0;i<t.size();i++){cout<<f?"":" "<<t[i];f=1;}cout<<endl;}
// template<typename T>inline void _output2(T t){for(int i=0;i<t.size();i++)output(t[i]);}
// #define rep(i,n) for(int i=0;i<int(n);++i)
// #define repi(i,a,b) for(int i=int(a);i<(int)(b);++i)
// #define rrep(i,n) for(int i=int(n)-1;i>=0;--i)
// #define rrepi(i,a,b) for(int i=int(b)-1;i>=int(a);--i)
// #define irep(i,n) for(int i=int(n);;++i)
// #define all(n) begin(n),end(n)
// inline auto gcd(auto A,auto B){return B?gcd(B,A%B):A;}
// inline auto lcm(auto A,auto B){return A/gcd(A,B)*B;}
// inline bool chmin(auto& s,const auto& t){bool res=s>t;s=min(s,t);return res;}
// inline bool chmax(auto& s,const auto& t){bool res=s<t;s=max(s,t);return res;}
// const vector<lint> dx={-1,1,0,0,1,1,-1,-1};
// const vector<lint> dy={0,0,-1,1,1,-1,1,-1};
// #define SUM(v) accumulate(all(v),0LL)
// auto call=[](auto f,auto... args){return f(f,args...);};

// template<typename X,typename Y,typename T,typename E>
// class segment2d{
//     class segment_y{
//         struct node{
//             np ch[2]={nullptr,nullptr};
//             E lazy=ee;
//             T val=e;
//             node(){}
//         };
//         private:
//         void update(int l,int r,int a,int b,E val,np t){
//             eval(t,l,r);
//             if(b<=l||r<=a)return;
//             if(l<=a&&b<=r){
//                 t->ch[0],
//                 eval(t,l,r);
//                 return;
//             }
//             t->ch[0]->update(lx,rx,ly,ry,a,(a+b)/2,val,t->ch[0]);
//             t->ch[1]->update(lx,rx,ly,ry,(a+b)/2,b,val,t->ch[1]);
//         }
//         E get(int lx,int rx,int ly,int ry,int a,int b,np t){
//             eval(t,lx,rx,ly,ry);
//             if(b<=lx||rx<=a)return e;
//             if(lx<=a&&b<=rx){
//                 return t->seg->get(ly,ry);
//             }
//             return f(t->ch[0]->get(l,r,a,(a+b)/2,val,t->ch[0]),t->ch[1]->get(l,r,(a+b)/2,b,val,t->ch[1]));
//         }
//         void evel(np t,int l,int r){
//             if(r-l>1){
//                 if(!t->ch[0])t->ch[0]=new node();
//                 if(!t->ch[1])t->ch[1]=new node();
//             }
//             t->val=g(t->val,t->lazy,l,r);
//             if(r-l>1){
//                 t->ch[0]->lazy=h(t->ch[0]->lazy,t->lazy);
//                 t->ch[1]->lazy=h(t->ch[1]->lazy,t->lazy);
//             }
//             t->lazy=ee;
//         }
//         void set_evel(E val){
//             root->lazy=h(root->lazy,val);
//         }
//     };
//     struct node;
//     using np=node*;
//     struct node{
//         np ch[2]={nullptr,nullptr};
//         E lazy=ee;
//         segment_y* seg=new segment_y();
//         node(){}
//     };
//     np root=nullptr;
//     vector<X>x_list;
//     vector<Y>y_list;
//     bool built=false;
//     public:
//     void setX(X x){
//         assert(!built);
//         x_list.push_back(x);
//     }
//     void setY(Y y){
//         assert(!built);
//         y_list.push_back(y);
//     }
//     void setXY(X x,Y y){
//         assert(!built);
//         x_list.push_back(x);
//         y_list.push_back(y);
//     }
//     private:
//     void update(int lx,int rx,int ly,int ry,int a,int b,E val,np t){
//         eval(t,lx,rx,ly,ry);
//         if(b<=lx||rx<=a)return;
//         if(lx<=a&&b<=rx){
//             t->lazy=g(t->lazy,val);
//             eval(t,lx,rx,ly,ry);
//             return;
//         }
//         t->ch[0]->update(lx,rx,ly,ry,a,(a+b)/2,val,t->ch[0]);
//         t->ch[1]->update(lx,rx,ly,ry,(a+b)/2,b,val,t->ch[1]);
//     }
//     E get(int lx,int rx,int ly,int ry,int a,int b,np t){
//         eval(t,lx,rx,ly,ry);
//         if(b<=lx||rx<=a)return e;
//         if(lx<=a&&b<=rx){
//             return t->seg->get(ly,ry);
//         }
//         return f(t->ch[0]->get(lx,rx,ly,ry,a,(a+b)/2,val,t->ch[0]),t->ch[1]->get(lx,rx,ly,ry,(a+b)/2,b,val,t->ch[1]));
//     }
//     void evel(np t,int l,int r,int ly,int ry){
//         if(r-l>1){
//             if(!t->ch[0])t->ch[0]=new node();
//             if(!t->ch[1])t->ch[1]=new node();
//         }
//         t->seg->set_eval(t->lazy);
//         if(r-l>1){
//             t->ch[0]->lazy=h(t->ch[0]->lazy,t->lazy,l,r);
//             t->ch[1]->lazy=h(t->ch[1]->lazy,t->lazy,l,r);
//         }
//         t->lazy=ee;
//     }
//     constexpr static int x_mx=1<<20;
//     constexpr static int y_mx=1<<20;
//     constexpr static T e=0;
//     constexpr static E ee=0;
// 	constexpr static
// 	T f(const T& s,const T& t){
// 		return s+t;
// 	}
//     constexpr static
//     E g(const E& s,const E& t){
// 		return s+t;
// 	}
//     constexpr static
//     T h(const T& s,const E& t){
// 		return s+t;
// 	}
// };


#include <bits/stdc++.h>
#define int long long
using namespace std;
using Graph = vector<vector<int>>;

signed main() {
  int N, aoki,taka;
  cin >> N >> taka >> aoki;
  
  Graph G(N);
  int A, B;
  for( int i = 0; i < N-1; i++ ){
    cin >> A >> B;
    G.at(A-1).push_back(B-1);
    G.at(B-1).push_back(A-1);
  }
  
  //青木君を根としてBFS
  vector<int> Adist(N, -1);
  queue<int> que;
  
  Adist.at(aoki-1) = 0;
  que.push(aoki-1);
  
  while( !que.empty() ){
    int v = que.front();
    que.pop();
    
    for( int nv : G.at(v) ){
      if( Adist.at(nv) != -1 ) continue;
      Adist.at(nv) = Adist.at(v)+1;
      que.push(nv);
    }
  }
  
  //高橋君から見てBFS
  vector<int> Tdist(N, -1);
  Tdist.at(taka-1) = 0;
  que.push(taka-1);
  
  while( !que.empty() ){
    int v = que.front();
    que.pop();
    
    for( int nv : G.at(v) ){
      if( Tdist.at(nv) != -1 ) continue;
      //青木君のほうが早く到達する頂点は無視
      if( Adist.at(nv) <= Tdist.at(v)+1 ) continue;
      
      Tdist.at(nv) = Tdist.at(v) + 1;
      que.push(nv);
    }
  }
  
  int ans = 0;
  for( int i = 0; i < N; i++ ){
    if( Tdist.at(i) != -1 && Adist.at(i)-1 > ans ) ans = Adist.at(i) - 1;
  }
  cout << ans << endl;
    
}
  
// int main(){
//     lint n;
//     cin>>n;
//     vec a(n),b(n);
//     vector<pair<lint,lint>>c(n);
//     rep(i,n){
//         cin>>a[i]>>b[i];
//         c[i]=make_pair(a[i]+b[i],i);
//     }
//     sort(all(c));
//     reverse(all(c));
//     lint ans=0;
//     rep(i,n){
//         if(i%2==0)ans+=a[c[i].second];
//         else ans-=b[c[i].second];
//     }
//     cout<<ans<<endl;
// }


Measured memory_bytes: 8064