#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
int acs(const void *a, const void *b){return *(int*)a - *(int*)b;} /* 1,2,3,4.. */
int des(const void *a, const void *b){return *(int*)b - *(int*)a;} /* 8,7,6,5.. */
int cmp_char(const void *a, const void *b){return *(char*)a - *(char*)b;} /* a,b,c,d.. */
int cmp_str(const void *a, const void *b){return strcmp(*(const char **)a, *(const char **)b);} /* aaa,aab.. */
#define min(a,b) (a < b ? a: b)
#define max(a,b) (a > b ? a: b)
#define rep(i, l, r) for (int i = l; i < r; i++)
#define MAX 100001
#define MOD 1000000007

typedef long long int lli;

typedef struct
{
  int front;
  int rear;
  int data[MAX][2];
} queue;

queue que;

void initQueue(queue *p)
{
  p->front = p->rear = 0;
}

bool emptyQueue(queue *p)
{
  return p->front == p->rear;
}

bool fullQueue(queue *p)
{
  return (p->front - 1 == p->rear) || (p->front == 0 && p->rear == MAX - 1);
}

void queuePop(queue *p)
{
  if (emptyQueue(p))
  {
    printf("UnderFlow\n");
    exit(1);
  }
  else
  {
    p->front++;
    if (p->front == MAX)
      p->front = 0;
  }
}

void queuePush(queue *p, int node, int parent)
{
  if (fullQueue(p))
  {
    printf("OverFlow\n");
    exit(1);
  }
  else
  {
    p->data[p->rear][0] = node;
    p->data[p->rear][1] = parent;
    p->rear++;
    if (p->rear == MAX)
      p->rear = 0;
  }
}

typedef struct list {
  int node;
  struct list *next;
} list;

list *graph[MAX];

void initGraph(void) {
  for (int i = 0; i < MAX; i++)
    graph[i] = NULL;
}

void addEdge(int node1, int node2)
{
  list *new1 = (list *)malloc(sizeof(list *));
  new1->node = node2;
  new1->next = graph[node1];
  graph[node1] = new1;

  list *new2 = (list *)malloc(sizeof(list *));
  new2->node = node1;
  new2->next = graph[node2];
  graph[node2] = new2;
}

int main(void) {
  int N, u, v, a, b;
  scanf("%d %d %d", &N, &u, &v);
  initGraph();
  rep(i, 0, N) {
    scanf("%d %d", &a, &b);
    addEdge(a, b);
  }

  int aoki[MAX]; // 青木くんのその頂点までの最短移動距離
  queue ki;
  initQueue(&ki);
  queuePush(&ki, v, 0);
  aoki[v] = 0;
  while ( !emptyQueue(&ki) ) {
    int n = ki.data[ki.front][0]; // 今
    int p = ki.data[ki.front][1]; // 親
    queuePop(&ki);
    taka[n] = taka[p] + 1;
    int count = 0;
    for (list *c = graph[n]; c != NULL; c = c->next) {
      if (c->node == p) continue;
      queuePush(&ki, c->node, n);
      count++;
    }
    if (count == 0) aoki[n] = 0;
  }

  int taka[MAX]; // 高橋くんのその頂点までの最短移動距離
  initQueue(&ki);
  queuePush(&ki, u, 0);
  taka[u] = 0;
  while ( !emptyQueue(&ki) ) {
    int n = ki.data[ki.front][0]; // 今
    int p = ki.data[ki.front][1]; // 親
    queuePop(&ki);
    taka[n] = taka[p] + 1;
    for (list *c = graph[n]; c != NULL; c = c->next) {
      if (c->node == p) continue;
      queuePush(&ki, c->node, n);
    }
  }

  int ans = 0;
  rep(node, 1, N + 1) {
    // 同じ回数で到達
    if (taka[node] > aoki[node]) continue;
    ans = max(ans, aoki[node]);
  }
  printf("%d\n", ans);
  return 0;
}
