#include <bits/stdc++.h>
using namespace std;
template <class T0, class T1>
class BaseLinkCutTree {
  virtual T0 f0(T0, T0) = 0;
  const T0 u0;
  virtual T1 f1(T1, T1) = 0;
  const T1 u1;
  virtual T0 g(T0, T1) = 0;
  virtual T1 p(T1, int) = 0;
  struct Node {
    int idx, cnt;
    T0 val, acc;
    T1 lazy;
    Node *left, *right, *par;
    Node(int idx, T0 val, T0 u0, T1 u1)
        : idx(idx),
          cnt(1),
          val(val),
          lazy(u1),
          acc(u0),
          left(nullptr),
          right(nullptr),
          par(nullptr) {}
    bool is_root() {
      return (!par) || (par->left != this && par->right != this);
    }
  };
  void push(Node* t) {
    if (t->cnt < 0) {
      swap(t->left, t->right);
      if (t->left) t->left->cnt = -(t->left->cnt);
      if (t->right) t->right->cnt = -(t->right->cnt);
      t->cnt = -t->cnt;
    }
    if (t->lazy != u1) {
      t->val = g(t->val, p(t->lazy, 1));
      t->acc = g(t->acc, p(t->lazy, t->cnt));
      if (t->left) t->left->lazy = g(t->left->lazy, p(t->lazy, 1));
      if (t->right) t->right->lazy = g(t->right->lazy, p(t->lazy, 1));
      t->lazy = u1;
    }
  }
  void eval(Node* t) {
    bool flag = (t->cnt < 0);
    t->cnt = 1, t->acc = t->val;
    if (t->left)
      push(t->left), t->cnt += _abs(t->left->cnt),
          t->acc = f1(t->left->acc, t->acc);
    if (t->right)
      push(t->right), t->cnt += _abs(t->right->cnt),
          t->acc = f1(t->acc, t->right->acc);
    if (flag) t->cnt = -t->cnt;
  }
  vector<Node*> nodes;
  inline static int _abs(int val) { return val & 0x7fffffff; }
  void rotate(Node* u, bool right) {
    Node *p = u->par, *g = p->par;
    if (right) {
      if ((p->left = u->right)) u->right->par = p;
      u->right = p, p->par = u;
    } else {
      if ((p->right = u->left)) u->left->par = p;
      u->left = p, p->par = u;
    }
    eval(p), eval(u), u->par = g;
    if (!g) return;
    if (g->left == p) g->left = u;
    if (g->right == p) g->right = u;
    eval(g);
  }
  void splay(Node* u) {
    while (!(u->is_root())) {
      Node *p = u->par, *gp = p->par;
      if (p->is_root()) {
        push(p), push(u);
        rotate(u, (u == p->left));
      } else {
        push(gp), push(p), push(u);
        bool flag = (u == p->left);
        if ((u == p->left) == (p == gp->left)) {
          rotate(p, flag), rotate(u, flag);
        } else {
          rotate(u, flag), rotate(u, !flag);
        }
      }
    }
    push(u);
  }
  Node* expose(Node* u) {
    Node* last = nullptr;
    for (Node* v = u; v; v = v->par) {
      splay(v);
      v->right = last;
      eval(v);
      last = v;
    }
    splay(u);
    return last;
  }
  bool connected(Node* u, Node* v) {
    expose(u), expose(v);
    return u->par;
  }
  void link(Node* u, Node* v) {
    assert(!connected(u, v));
    evert(u), u->par = v;
  }
  void cut(Node* u) {
    expose(u);
    assert(u->left);
    u->left->par = nullptr, u->left = nullptr, eval(u);
  }
  Node* lca(Node* u, Node* v) {
    expose(u);
    return expose(v);
  }
  Node* get_kth(Node* v, int k) {
    expose(v);
    while (v) {
      eval(v);
      if (v->right && v->right->cnt > k) {
        v = v->right;
      } else {
        if (v->right) k -= v->right->cnt;
        if (k == 0) return v;
        k--;
        v = v->left;
      }
    }
    return nullptr;
  }
  Node* get_root(Node* v) {
    expose(v);
    while (v->left) {
      eval(v);
      v = v->left;
    }
    return v;
  }
  void evert(Node* u) { expose(u), u->cnt = -(u->cnt); }
  int depth(Node* u) {
    expose(u);
    return _abs(u->cnt) - 1;
  }
  void update(Node* u, Node* v, const T1 x) {
    evert(u), expose(v);
    v->lazy = f1(v->lazy, x), push(v);
  }
  T0 query(Node* u, Node* v) {
    evert(u), expose(v);
    return v->acc;
  }

 public:
  BaseLinkCutTree(T0 u0, T1 u1) : u0(u0), u1(u1) {}
  int make_new_node(T0 v) {
    int idx = nodes.size();
    nodes.push_back(new Node(idx, v, u0, u1));
    return idx;
  }
  bool connected(int a, int b) { return connected(nodes[a], nodes[b]); }
  void link(int u, int v) { return link(nodes[u], nodes[v]); }
  void cut(int v) { return cut(nodes[v]); }
  int lca(int u, int v) { return lca(nodes[u], nodes[v])->idx; }
  int get_kth(int v, int k) { return get_kth(nodes[v], k)->idx; }
  int get_root(int v) { return get_root(nodes[v])->idx; }
  void evert(int v) { return evert(nodes[v]); }
  int depth(int v) { return depth(nodes[v]); }
  int dist(int u, int v) { return depth(u) + depth(v) - 2 * depth(lca(u, v)); }
  void update(int u, int v, T1 x) { return update(nodes[u], nodes[v], x); }
  void update(int v, T1 x) { update(v, v, x); }
  T0 query(int u, int v) { return query(nodes[u], nodes[v]); }
  T0 query(int v) { return query(v, v); }
};
template <class T0, class T1>
struct MinUpdateQuery : public BaseLinkCutTree<T0, T1> {
  using BaseLinkCutTree<T0, T1>::BaseLinkCutTree;
  MinUpdateQuery()
      : MinUpdateQuery(numeric_limits<T0>::max(), numeric_limits<T1>::min()) {}
  T0 f0(T0 x, T0 y) override { return min(x, y); }
  T1 f1(T1 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
  T0 g(T0 x, T1 y) override { return y == numeric_limits<T1>::min() ? x : y; }
  T1 p(T1 x, int len) override { return x; }
};
int main() {
  MinUpdateQuery<int, int> lct;
  int n, u, v;
  cin >> n >> u >> v;
  u--, v--;
  for (int i = 0; i < n; i++) {
    lct.make_new_node(0);
  }
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    lct.link(a, b);
  }
  lct.evert(u);
  int dist = lct.dist(u, v);
  if (dist == 1) {
    cout << 0 << endl;
    return 0;
  }
  int w = lct.get_kth(v, (dist - 2) / 2);
  int nax = 0;
  for (int i = 0; i < n; i++) {
    if (lct.lca(i, w) == w) {
      nax = max(nax, lct.depth(i));
    }
  }
  cout << (dist - 2) / 2 + nax - 1 << endl;
}
