import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.io.PrintWriter
import java.util.*

class Edge(val node:Int, val cost:Int)
class State(val cost:Int, val position:Int, val prenode:Int) : Comparable<State> {
    override fun compareTo(other: State): Int {
        return if (cost == other.cost) position.compareTo(other.position) else cost.compareTo(other.cost)
    }
}

fun dijkstra(adj: Array<MutableList<Edge>>, start: Int): Array<Int> {
    val n = adj.count()
    val dist = Array(n) { Int.MAX_VALUE }
    val preNodes = (0 until n).toMutableList()
    val heap = PriorityQueue<State>()
    dist[start] = 0
    heap.add(State(0, start, 0))
    while (heap.count() > 0) {
        val state = heap.poll()
        val cost = state.cost
        val position = state.position
        val prenode = state.prenode
        if (cost > dist[position]) continue
        preNodes[position] = prenode
        for (edge in adj[position]) {
            val next = State(cost + edge.cost, edge.node, position)
            if (next.cost < dist[next.position]) {
                heap.add(next)
                dist[next.position] = next.cost
            }
        }
    }
    return dist
}

fun PrintWriter.solve(sc: FastScanner) {
    val v = sc.nextInt()
    val e = sc.nextInt()
    val r = sc.nextInt()
    val adj = Array(v) { mutableListOf<Edge>() }
    for (i in 0 until e) {
        val s = sc.nextInt()
        val t = sc.nextInt()
        val d = sc.nextInt()
        adj[s].add(Edge(t, d))
    }
    val dist = dijkstra(adj, r)
    for (d in dist) {
        if (d == Int.MAX_VALUE) {
            println("INF")
        } else {
            println(d)
        }
    }
}

fun main(args: Array<String>) {
    val writer = PrintWriter(System.out, false)
    writer.solve(FastScanner(System.`in`))
    writer.flush()
}

class FastScanner(s: InputStream) {
    private var st = StringTokenizer("")
    private val br = BufferedReader(InputStreamReader(s))

    fun next(): String {
        while (!st.hasMoreTokens()) st = StringTokenizer(br.readLine())

        return st.nextToken()
    }

    fun nextInt() = next().toInt()
    fun nextLong() = next().toLong()
    fun nextLine() = br.readLine()
    fun nextDouble() = next().toDouble()
    fun ready() = br.ready()
}

