#include <bits/stdc++.h>
using namespace std;
using Int = long long;
#define REP2(i, n) for (Int i = 0, max_i = (n); i < max_i; i++)
#define REP3(i, a, b) for (Int i = (a), max_i = (b); i < max_i; i++)
#define OVERLOAD2(_1, _2, _3, name, ...) name
#define REP(...) OVERLOAD2(__VA_ARGS__, REP3, REP2)(__VA_ARGS__)
template <class T> inline bool chmax(T& a, const T& b) {
    if (a >= b) return false;
    a = b;
    return true;
}
template <class T> inline bool chmin(T& a, const T& b) {
    if (a <= b) return false;
    a = b;
    return true;
}
struct in {
    int n;
    in() {}
    in(int n_) : n(n_){};
    template <class T> operator T() {
        T ret;
        cin >> ret;
        return ret;
    }
    template <class T> operator vector<T>() {
        vector<T> ret(n);
        for (int i = 0; i < n; i++) cin >> ret[i];
        return ret;
    }
};
struct SetupIO {
    SetupIO() { cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(20); }
} setup_io;

#ifdef _MY_DEBUG
#include "/Users/knshnb/.competitive_local.hpp"
#else
#define dump(...)
#endif

/**
 *    author:  knshnb
 *    created: Mon Dec 23 15:27:01 JST 2019
 **/

// edgeを貼ったあとにbuild()を忘れない！
struct TreeDoubling {
    struct Edge {
        int to;
        // int to, color, len;
    };  // 場合に応じて書き換える、toは必須
    vector<vector<Edge>> g;
    int n, size;  // MSB + 1
    int root;
    vector<int> depth;
    vector<vector<int>> parent;  // ダミー頂点n(親もn)
    TreeDoubling(int n) : g(n), n(n), depth(n), size(64 - __builtin_clzll(n)) {
        parent.resize(size, vector<int>(n + 1, n));
    }
    void dfs(int v, int prev, int d) {
        depth[v] = d;
        parent[0][v] = prev;
        for (auto& s : g[v])
            if (s.to != prev) {
                dfs(s.to, v, d + 1);
            }
    }
    void build(int root_ = 0) {
        root = root_;
        dfs(root, n, 0);
        for (int k = 0; k < size - 1; k++) {
            for (int i = 0; i < n; i++) {
                parent[k + 1][i] = parent[k][parent[k][i]];
            }
        }
    }

    // vからd個分親にさかのぼった頂点、rootよりも上はnを返す
    int query(int v, int d) {
        int ret = v;
        for (int j = 0; j < size; j++) {
            if (d >> j & 1) ret = parent[j][ret];
        }
        return ret;
    }
    int lca(int u, int v) {
        if (depth[u] > depth[v]) swap(u, v);
        v = query(v, depth[v] - depth[u]);
        if (u == v) return u;

        for (int j = size - 1; j >= 0; j--) {
            if (parent[j][u] == parent[j][v]) continue;
            u = parent[j][u];
            v = parent[j][v];
        }
        assert(parent[0][u] == parent[0][v]);
        return parent[0][u];
    }
    int dist(int u, int v) {
        return depth[u] + depth[v] - depth[lca(u, v)] * 2;
    }
};

signed main() {
    Int n = in();
    Int U = in(), V = in();
    U--, V--;
    TreeDoubling td(n);
    REP(i, n - 1) {
        int u = in(), v = in();
        u--, v--;
        td.g[u].push_back({v});
        td.g[v].push_back({u});
    }
    td.build();
    Int ans = 0;
    REP(i, n) {
        if (td.dist(U, i) < td.dist(V, i)) {
            chmax(ans, (Int)td.dist(V, i) - 1);
        }
    }
    cout << ans << endl;
}


Measured memory_bytes: 15352