#include <bits/stdc++.h>
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
using i64 = int64_t;
using f80 = __float80;
static const int dy[4] = {0,1,0,-1}, dx[4] = {1,0,-1,0};
constexpr i64 INF = 1'010'000'000'000'000'017LL;
constexpr i64 MOD = 1'000'000'007LL;
#define _overload3(_1,_2,_3,name,...) name
#define repi(i,start,end) for(i64 i=(start);i<(end);++i)
#define _rep(i,n) repi(i,0,n)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define rrep(i,start,end) for(i64 i=(start);i>end;--i)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define isin(x,l,r) ((l) <= (x) && (x) < (r))
#define show(x) cout<<#x<<" = "<<x<<endl;
#define PQ(T) priority_queue<T,v(T),greater<T> >
#define v(T) vector<T>
#define vv(T) v(v(T))
typedef v(i64) vi;
typedef v(vi) vvi;
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return true;}return false;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return true;}return false;}
template<typename T> ostream &operator<<(ostream &os, const vector< T > &v){
  rep(i,v.size()) os << v[i] << (i + 1 != v.size() ? " " : "");
  return os;
}
template<typename T> istream &operator>>(istream &is, vector< T > &v){
  for(T &in : v) is >> in;
  return is;
}

//sort(rng(P),[](const vi &a, const vi &b){return a[1]<b[1];});

i64 pow_mod(i64 n, i64 k, i64 m){
  i64 r = 1;
  for(;k;k>>=1){
    if(k&1) r=(r*n)%m;
    n=(n*n)%m;
  }
  return r;
}

struct uf{
  private:
    vi par, rank, size;
  public:
    uf(i64 n){ init(n); }
    void init(i64 n){
      par.resize(n);
      rank.resize(n,0);
      size.resize(n,1);
      rep(i,n) par[i] = i;
    }
    i64 root(i64 x){
      if(par[x] == x) return x;
      return par[x] = root(par[x]);
    }
    bool same(i64 x, i64 y){ return root(x) == root(y); }
    void unite(i64 x, i64 y){
      x = root(x), y = root(y);
      if(x==y) return;
      if(rank[x]==rank[y]) rank[x]++;
      if(rank[x]<rank[y]) swap(x,y);
      par[y] = x;
      size[x] += size[y];
    }
    i64 num(i64 x){ return size[root(x)]; }
};

void Main()
{
  i64 N, A, B;
  cin >> N >> A >> B;
  A--;
  B--;

  vvi G(N);
  i64 a, b;
  rep(i,N-1){
    cin >> a >> b;
    a--;
    b--;
    G[a].emplace_back(b);
    G[b].emplace_back(a);
  }

  vi dist_A(N,INF);
  dist_A.at(A) = 0;
  queue<pair<i64,i64>> que;
  que.push(make_pair(A,0));
  while(!que.empty()){
    i64 cur_pos = que.front().first;
    i64 cur_dist = que.front().second;
    que.pop();
    for(auto &p:G[cur_pos]){
      if(dist_A.at(p)<INF) continue;
      dist_A.at(p) = cur_dist + 1;
      que.push(make_pair(p,cur_dist + 1));
    }
  }

  vi dist_B(N,INF);
  dist_B.at(B) = 0;
  que.push(make_pair(B,0));
  while(!que.empty()){
    i64 cur_pos = que.front().first;
    i64 cur_dist = que.front().second;
    que.pop();
    for(auto &p:G[cur_pos]){
      if(dist_B.at(p)<INF) continue;
      dist_B.at(p) = cur_dist + 1;
      que.push(make_pair(p,cur_dist + 1));
    }
  }

  i64 ans = 0;
  rep(i,N){
    if(dist_A[i]<dist_B[i]) chmax(ans,dist_B[i]-1);
  }

  cout << ans << "\n";
}

int main()
{
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  Main();
}

Measured memory_bytes: 8192