#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <algorithm>
#include <utility>
#include <numeric>
#include <deque>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cmath>
#include <limits>
#include <cassert>
#include <bitset>

#define for0(i, N)    for (int i = 0  ; i <  (N); ++i)
#define for1n(i, N)   for (int i = 1  ; i <= (N); ++i)
#define for1(i, N)    for (int i = 1  ; i <  (N); ++i)
#define forn(i, N)    for (int i = 0  ; i <= (N); ++i)
#define forx(i, N, x) for (int i = (x); i <  (N); ++i)
#define forl(i, N, x, a) for (int i = (x), a = 0; a < (N);  \
                              i = (i + 1) % (N), ++a)

template<size_t i>
std::bitset<i> operator++(std::bitset<i> b, int){
    static_assert(i <= 64, "Cannot cast 64bit int.");
    return b = (unsigned long long)b + 1;
}

template<size_t i>
std::bitset<i> operator++(std::bitset<i> b){
    static_assert(i <= 64, "Cannot cast 64bit int.");
    auto temp = b;
    b++;
    return temp;
}

template<size_t i>
std::bitset<i> operator--(std::bitset<i> b, int){
    static_assert(i <= 64, "Cannot cast 64bit int.");
    return b = (unsigned long long)b - 1;
}

template<size_t i>
std::bitset<i> operator--(std::bitset<i> b){
    static_assert(i <= 64, "Cannot cast 64bit int.");
    auto temp = b;
    b--;
    return temp;
}

using namespace std;

typedef long long ll;
typedef long double ld;
typedef priority_queue<ll> pq;
typedef priority_queue<ll,vector<ll>, greater<ll>> pql;
typedef stack<ll> stk;
typedef queue<ll> qu;
typedef pair<ll, ll> pll;
typedef map<ll, ll> mll;
typedef unordered_map<ll, ll> umll;
typedef set<ll> sll;
typedef unordered_set<ll> usll;

struct arc{
    int to;
    int cost;
    bool operator==(arc const &a) const {
        return to == a.to && cost == a.cost;
    }
};

template<typename T>
struct node{
    T value;
    vector<arc> arcs;
    node(T v) : value(v){}

    node& operator= (T const& a){
        value = a;
        return *this;
    }
    operator T() const {
        return value;
    }

};

template<typename T>
class graph{
protected:
    vector<node<T>> nodes;
    int n;
public:

    graph(int N, T value) : nodes(N, value), n(N){};

    void addArc(int from, int to, int cost){
        assert(0 <= from && from <= n - 1 && 0 <= to && to <= n - 1);
        nodes[from].arcs.push_back({to,cost});
    }
    void addEdge(int a, int b, int cost){
        addArc(a, b, cost);
        addArc(b, a, cost);
    }
    node<T>& operator[](int index) {
        return nodes[index];
    }

    auto begin() { return nodes.begin(); }
    auto end()   { return nodes.end();   }

    auto const& getInstance(){
        return nodes;
    }

};

class bellmanford : public graph<int>{
    int N;
    int changed;

    void r(unordered_set<int> froms, int termination){
        bool c = false;
        unordered_set<int> f;
        for (auto& from : froms){
            for (auto& i : nodes[from].arcs) {
                if (nodes[i.to].value > i.cost + nodes[from].value) {
                    nodes[i.to].value = i.cost + nodes[from].value;
                    f.insert(i.to);
                    c = true;
                }
            }
        }
        // Terminated
        if (!c) return;

        // Negative loop?
        if(!termination){
            changed = c;
            return;
        }
        // continue
        r(move(f), termination-1);
    }

public:

    bellmanford(int N): graph::graph(N, std::numeric_limits<int>::max()),
                        N(N), changed(false){}

    bool run(int start){
        nodes[start].value = 0;
        r({start}, N - 1);
        return changed;
    }

    int const& operator[] (int index){
        return nodes[index].value;
    }

};

ll h(graph<int> &g, int parent, int bad, int counter=0){
    if (g.getInstance().at(parent).arcs.size() == 1) {
            return counter;
    }

    ll result = 0;

    for(auto &x : g.getInstance().at(parent).arcs){
        if (x.to == bad) continue;
        result = max(result, h(g, x.to, parent, counter+1));
    }
    return result;
}

int f(graph<int> &g, int parent, int child){
    if (parent == child) {
        return h(g, child, parent);
    }

    for(auto x : g.getInstance().at(parent).arcs){
        auto r = f(g, x.to, child);
        if (r >= 0)
            return r;
    }
    return -1;
}

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

    int n, u, v;
    cin >> n >> u >> v;

    bellmanford g(n);

    bellmanford es(n);


    for0(i, n - 1){
        int a, b;
        cin >> a >> b;
        g.addEdge(a - 1, b - 1, 1);
        es.addEdge(a - 1, b - 1, 1);
    }

    g.run(v - 1);
    es.run(u - 1);

    int result = 0;

    if (find(g.getInstance()[v - 1].arcs.cbegin(),
             g.getInstance()[v - 1].arcs.cend(), arc{u - 1, 1})
        != g.getInstance()[v - 1].arcs.cend()) {
        cout << 0;
        return 0;
    }

    for0(i, n){
        auto &o = g.getInstance()[i];
        auto &e = es.getInstance()[i];

        if (o.arcs.size() == 1 && o.value > e.value) {
            result = max(result, o.value);
        }
    }

    cout << result;

    return 0;
}
