#include <bits/stdc++.h>

using namespace std;

#define SZ(x) (int)(x.size())

using ll = long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const double eps = 1e-10;
const int MOD = 1000000007;
const ll LINF = 1ll<<50;

template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}

using cost_t=int;

struct Edge {
    int from, to;
    cost_t cost;
    Edge(int from, int to, cost_t cost) : from(from), to(to), cost(cost) {}
};

using Edges = vector<Edge>;
using Graph = vector<Edges>;


struct LCA{
    static const int LOGN=20;
    array<vector<int>,LOGN+1> par;
    vector<int> dep;
    void dfs(int v,int pre,Graph& g){
        for(auto& e:g[v]){
            if(e.to==pre) continue;
            par[0][e.to]=v;
            dep[e.to]=dep[v]+1;
            dfs(e.to,v,g);
        }
    }

    LCA(Graph& g,int root):dep(g.size()){
        int n=g.size();
        for(int i=0;i<=LOGN;i++) par[i].assign(n,-1);
        dep[root]=0;
        par[0][root]=root;
        dfs(root,-1,g);
        for(int i=0;i<LOGN;i++){
            for(int j=0;j<n;j++){
                par[i+1][j]=par[i][par[i][j]];
            }
        }
    }

    int query(int u,int v){
        if(dep[u]<dep[v]) swap(u,v);
        int d = dep[u]-dep[v];
        for(int i=LOGN;i>=0;i--){
            if((d>>i)&1){
                u = par[i][u];
                d-=(1<<i);
            }
        }
        if(u==v) return u;
        for(int i=LOGN;i>=0;i--){
            if(par[i][u]!=par[i][v]) u=par[i][u],v=par[i][v];
        }
        return par[0][u];
    }
};

const cost_t INF=1e9+9; // must edit this
void dijkstra(int s,Graph& g,vector<cost_t>& d){
    int n=g.size();
    d.assign(n,INF);
    d[s]=0;
    using Item=pair<cost_t,int>;
    priority_queue<Item,vector<Item>,greater<Item>> que;
    que.push(Item(0,s));
    while(!que.empty()){
        auto tmp=que.top(); que.pop();
        int v=tmp.second;
        if(d[v]<tmp.first) continue;
        for(auto &e:g[v]){
            if(d[v]+e.cost<d[e.to]){
                d[e.to]=d[v]+e.cost;
                que.push(Item(d[e.to],e.to));
            }
        }
    }
}

void dfs(int now, int prev, const Graph &tr, Graph &tr2) {
  for(int i=0;i<SZ(tr[now]);++i) {
    int nxt = tr[now][i].to;
    if(nxt == prev) continue;
    tr2[now].push_back(Edge(now, nxt, 1));
    dfs(nxt, now, tr, tr2);
  }
}

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

  int n; cin >> n;
  int u, v; cin >> u >> v;
  u--; v--;
  Graph tr(n);
  vi dim(n);
  for(int i=0;i<n-1;++i) {
    int a, b; cin >> a >> b;
    a--; b--;


    dim[a]++;
    dim[b]++;
    tr[a].emplace_back(Edge(a, b, 1));
    tr[b].emplace_back(Edge(b, a, 1));
  }

  Graph tr2(n);
  dfs(u, -1, tr, tr2);

  vi leaf;
  for(int i=0;i<n;++i) {
    if(dim[i] == 1) leaf.push_back(i);
  }
  //printv(leaf);

  LCA lca(tr2, u);

  vi taka, ao;
  dijkstra(u, tr, taka);
  dijkstra(v, tr, ao);

  int ma = taka[v] - 1;
  for(int i=0;i<SZ(leaf);++i) {
    if(leaf[i] == u || leaf[i] == v) continue;
    int now = lca.query(v, leaf[i]);
    //cout << leaf[i] << ":" << mpinv[now]-1 << ":" << now << endl;
    //cout << leaf[i] << ":" << now << endl;
    if(taka[now] >= ao[now]) continue;
    ma = max(ma, ao[leaf[i]]-1);
  }
  
  cout << ma << endl;

}


Measured memory_bytes: 28288