#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 100001
#define TRUE 1
#define FALSE 0
typedef struct GraphNode{
int vertex;
struct GraphNode *link;
} GraphNode;
typedef struct GraphType{
int n;
GraphNode *adj_list[MAX_VERTICES];
} GraphType;
typedef struct Queue{
int items[MAX_VERTICES];
int front, rear;
} Queue;
void init_Queue(Queue *q){
q->front = q->rear = 0;
}
void enqueue(Queue *q, int value){
if(q->rear > MAX_VERTICES){
fprintf(stderr, "queue overflow");
return;
}
q->items[q->rear++] = value;
}
int is_Empty(Queue *q){
return q->front == q->rear;
}
int dequeue(Queue *q){
if(is_Empty(q)){
fprintf(stderr, "queue empty");
return 0;
}
return q->items[q->front++];
}
int visited[MAX_VERTICES];
int i = 1;
void init(GraphType *g){
g->n = 0;
for(int v=0; v<MAX_VERTICES; v++){
g->adj_list[v] = NULL;
}
}
void insert_vertex(GraphType *g, int v){
if(((g->n)+1)>MAX_VERTICES){
fprintf(stderr, "vertex overflow");
return;
}
g->n++;
}
void insert_edge(GraphType *g, int u, int v){
GraphNode *node;
if(u>=MAX_VERTICES || v>=MAX_VERTICES){
fprintf(stderr, "edge error");
return;
}
node = (GraphNode*)malloc(sizeof(GraphNode));
node->vertex = v;
node->link = g->adj_list[u];
g->adj_list[u] = node;
}
void split_list(GraphNode *node, GraphNode **front, GraphNode **back){
GraphNode *fast, *slow;
slow = node;
fast = node->link;
while(fast != NULL){
fast = fast->link;
if(fast != NULL){
slow = slow->link;
fast = fast->link;
}
}
*front = node;
*back = slow->link;
slow->link = NULL;
}
GraphNode *sorted_merge(GraphNode *front, GraphNode *back){
GraphNode *res;
if(front == NULL){
return back;
}
if(back == NULL){
return front;
}
if(front->vertex > back->vertex){
res = back;
res->link = sorted_merge(front, back->link);
} else{
res = front;
res->link = sorted_merge(front->link, back);
}
return res;
}
GraphNode *merge_sort(GraphNode *node){
if(node == NULL || node->link == NULL){
return node;
}
GraphNode *a;
GraphNode *b;
split_list(node, &a, &b);
a = merge_sort(a);
b = merge_sort(b);
return sorted_merge(a,b);
}
void bfs(GraphType *g, int start){
GraphNode *node;
Queue *q;
q = (Queue*)malloc(sizeof(Queue));
init_Queue(q);
visited[start] = i++;
enqueue(q, start);
while(!is_Empty(q)){
start = dequeue(q);
for(node = merge_sort(g->adj_list[start]); node!=NULL; node = node->link){
if(!visited[node->vertex]){
visited[node->vertex] = i++;
enqueue(q, node->vertex);
}
}
}
}
void print_list(GraphType *g){
GraphNode *node;
int r,c;
for(r=1; r<=g->n; r++){
printf("%d : ", r);
for(node = g->adj_list[r]; node != NULL; node = node->link){
printf("%d -> ", node->vertex);
}
printf("\n");
}
}
int main(){
GraphType *g;
g = (GraphType*)malloc(sizeof(GraphType));
init(g);
int vertex, edge, start;
scanf("%d %d %d", &vertex, &edge, &start);
for(int i=0; i<vertex; i++){
insert_vertex(g, i);
}
int e1, e2;
for(int i=0; i<edge; i++){
scanf("%d %d", &e1, &e2);
insert_edge(g, e1, e2);
insert_edge(g, e2, e1);
}
bfs(g, start);
for(int i=1; i<=g->n; i++){
if(visited[i] == 0){
printf("0\n");
} else{
printf("%d\n", visited[i]);
}
}
free(g);
return 0;
}