//
//  main.cpp
//

#include <algorithm>
#include <array>
#include <assert.h>
#include <iomanip>
#include <iostream>
#include <limits>
#include <math.h>
#include <memory>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = int64_t;
using ull = uint64_t;

template<typename T>
vector<T> make_vec_nd(T init, ll size) {
    return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, ll size, Args... rest) {
    auto inner = make_vec_nd(init, rest...);
    return vector<decltype(inner)>(size, inner);
}

#define rep(i,a,b) for(ll i=(a);i<(b);i++)
#define rrep(i,a,b) for(ll i=(a)-1;i>=(b);i--)

struct RootTree {
    struct Node {
        ll parent = -1;
        vector<ll> child;
    };
    vector<Node> nodes;
    RootTree(size_t n) { nodes = vector<Node>(n, Node{-1, {}}); }
    void set_child(ll p, ll c) {
        assert(0 <= p && p < nodes.size());
        assert(0 <= c && c < nodes.size());
        assert(nodes[c].parent == -1);
        nodes[p].child.push_back(c);
        nodes[c].parent = p;
    }
    vector<vector<ll>> doubling_parents_table() {
        // return[k][i] = ノードiから2^k登ったところにあるノード（ルートを超える時は-1）
        vector<vector<ll>> ans;
        int k = 0;
        while (true) {
            ans.push_back(vector<ll>(nodes.size(), -1));
            bool proceed = false;
            for (int i = 0; i < nodes.size(); i++) {
                if (k == 0) {
                    ans[k][i] = nodes[i].parent;
                } else {
                    ll half = ans[k - 1][i];
                    if (half == -1) {
                        ans[k][i] = -1;
                    } else {
                        ans[k][i] = ans[k - 1][half];
                    }
                }
                if (ans[k][i] != -1) {
                    proceed = true;
                }
            }
            if (!proceed) {
                break;
            }
            k++;
        }
        return ans;
    }
    vector<ll> depth_table(ll root) {
        // return[i] = ノードiの深さ
        vector<ll> ans(nodes.size(), -1);
        vector<ll> stack;
        stack.push_back(root);
        ans[root] = 0;
        while (stack.size() > 0) {
            ll node = stack.back();
            stack.pop_back();
            assert(ans[node] != -1);
            for (ll child : nodes[node].child) {
                ans[child] = ans[node] + 1;
                stack.push_back(child);
            }
        }
        return ans;
    }
    ll lca(ll a, ll b, const vector<ll>& depth,
               const vector<vector<ll>>& parent) {
        assert(0 <= a && a < nodes.size());
        assert(0 <= b && b < nodes.size());
        if (depth[a] != depth[b]) {
            if (depth[a] < depth[b]) {
                swap(a, b);
            }
            ll diff = depth[a] - depth[b];
            while (diff != 0) {
                int n = 0;
                while (true) {
                    if (diff < (1 << (n + 1))) {
                        break;
                    }
                    n++;
                }
                assert(diff >= (1 << n));
                a = parent[n][a];
                diff = depth[a] - depth[b];
            }
        }
        while (true) {
            if (a == b) {
                return a;
            }
            if (parent[0][a] == parent[0][b]) {
                return parent[0][a];
            }
            int n = 0;
            while (true) {
                if (parent[n + 1][a] == parent[n + 1][b]) {
                    break;
                }
                n++;
            }
            a = parent[n][a];
            b = parent[n][b];
        }
    }
};

vector<vector<ll>> graph;
vector<bool> visited;
RootTree tree(0);

void create_tree(ll now) {
    visited[now] = true;
    for (ll to : graph[now]) {
        if (!visited[to]) {
            tree.set_child(now, to);
            create_tree(to);
        }
    }
}

int main() {
    ll N, tak, ao;
    cin >> N >> tak >> ao;
    tak--;
    ao--;
    graph.resize(N);
    rep(i,0,N-1) {
        ll A, B;
        cin >> A >> B;
        A--;
        B--;
        graph[A].push_back(B);
        graph[B].push_back(A);
    }
    ll ans = numeric_limits<ll>::min();
    tree = RootTree(N);
    visited.resize(N);
    create_tree(ao);
    vector<ll> depth = tree.depth_table(ao);
    vector<vector<ll>> parent_table = tree.doubling_parents_table();
    rep(node_idx, 0, N) {
        RootTree::Node node = tree.nodes[node_idx];
        if (node.child.size() > 0) {
            continue;
        }
        ll lca = tree.lca(tak, node_idx, depth, parent_table);
        ll dist_tak = depth[tak] - depth[lca];
        ll dist_ao = depth[lca];
        if (!(dist_tak < dist_ao)) {
            continue;
        }
        ll dep = depth[node_idx];
        ans = max(ans, dep - 1);
    }
    cout << ans << endl;
}



Measured memory_bytes: 30720