#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct node {
  int id;
  int weight;
  struct node *next;
};
struct node **list;
int *dist, *prev, *heap, *heap_index, heapsize;
void Insert(int, int, int);
void downheap(int);
void upheap(int);
void PQ_Init(int);
void DijkstraPQ(int, int);
int main(void)
{
  int i, n, r, u, v, c, q;
  scanf("%d %d %d", &n, &r, &q);
  list = (struct node**)malloc(sizeof(struct node*) * n);
  for (i = 0; i < n; i++) {
    list[i] = NULL;
  }
  dist = (int*)malloc(sizeof(int) * n * 2);
  prev = (int*)malloc(sizeof(int) * n);
  for (i = 0; i < r; i++) {
    scanf("%d %d %d", &u, &v, &c);
    Insert(u, v, c);
  }
  DijkstraPQ(q, n * 2);
  //printf("%d\n", dist[2*n-1]);
  for (i = 0; i < n; i++) {
    struct node *p, *q;
    if (dist[i] < INT_MAX) {
      printf("%d\n", dist[i]);
    } else {
      printf("INF\n");
    }
    if (list[i] != NULL) {
      for (q = list[i], p = q->next; p != NULL; q = p, p = p->next) {
        q->next = p->next;
        free(p);
      }
      free(list[i]);
    }
  }
  free(list);
  free(dist);
  free(prev);
  free(heap);
  free(heap_index);
}
void Insert(int a, int b, int weight)
{
  struct node *p = (struct node*)malloc(sizeof(struct node));
  p->id = b;
  p->weight = weight;
  p->next = list[a];
  list[a] = p;
}
void downheap(int k)
{
  int j, v = heap[k];
  while (k < heapsize / 2) {
    j = 2 * k + 1;
    if (j < heapsize - 1 && dist[heap[j]] > dist[heap[j + 1]]) j++;
    if (dist[v] <= dist[heap[j]]) break;
    heap[k] = heap[j];
    heap_index[heap[j]] = k;
    k = j;
  }
  heap[k] = v;
  heap_index[v] = k;
}
void upheap(int j)
{
  int k, v = heap[j];
  while (j > 0) {
    k = (j + 1) / 2 - 1;
    if (dist[v] >= dist[heap[k]]) break;
    heap[j] = heap[k];
    heap_index[heap[k]] = j;
    j = k;
  }
  heap[j] = v;
  heap_index[v] = j;
}
void PQ_Init(int size)
{
  int i;
  heapsize = size;
  heap = (int*)malloc(sizeof(int) * size);
  heap_index = (int*)malloc(sizeof(int) * size);
  for (i = 0; i < size; i++) {
    heap[i] = i;
    heap_index[i] = i;
  }
  for (i = size / 2 - 1; i >= 0; i--) {
    downheap(i);
  }
}
void DijkstraPQ(int p, int size)
{
  int i;
  for (i = 0; i < size; i++) dist[i] = INT_MAX;
  for (i = 0; i < size / 2; i++) prev[i] = -1;
  dist[p] = 0;
  PQ_Init(size);
  while (heapsize > 0) {
    struct node *n;
    int u = heap[0];
    heap[0] = heap[heapsize - 1];
    heap_index[heap[heapsize - 1]] = 0;
    heapsize--;
    downheap(0);
    for (n = list[u%(size/2)]; n != NULL; n = n->next) {
      long int w = n->weight, newlen2 = dist[u] + w;
      if (newlen2 < dist[n->id]) {
        int temp = newlen2;
        newlen2 = dist[n->id];
        dist[n->id] = temp;
        upheap(heap_index[n->id]);
      }
      if (newlen2 < dist[n->id+size/2]) {
        dist[n->id+size/2] = newlen2;
        upheap(heap_index[n->id+size/2]);
      }
    }
  }
}
