from heapq import heappush, heappop

V, E, r = list(map(int, input().split()))

g = [[] for i in range(V)]

for i in range(E):

    s, t, d = list(map(int, input().split()))

    g[s].append((t, d))



INF = 10**10

dist = [INF]*V

que = [(0,r)]

dist[r] = 0

while que:

    c, v = heappop(que)

    if dist[v] < c:

        continue

    for t, cost in g[v]:

        if dist[v] + cost < dist[t]:

            dist[t] = dist[v] + cost

            heappush(que, (dist[t], t))

for i in range(V):

    print(dist[i] if dist[i]<INF else "INF")
class RadixHeap:

    __slots__ = ["data", "last", "siz", "used"]



    # (max_key - min_key) <= C

    def __init__(self, N, C):

        self.data = [[] for i in range(C.bit_length() + 1)]

        self.last = self.siz = 0

        self.used = [0]*N



    def push(self, x, key):

        #assert self.last <= x

        self.siz += 1

        self.data[(x ^ self.last).bit_length()].append((x, key))



    def pop(self):

        data = self.data

        used = self.used

        #assert self.siz > 0

        if not data[0]:

            i = 1

            while not data[i]:

                i += 1

            d = data[i]

            new_last, new_key = min(d)

            used[new_key] = 1

            for val in d:

                x, key = val

                if used[key]:

                    self.siz -= 1

                    continue

                data[(x ^ new_last).bit_length()].append(val)

            self.last = new_last

            data[i] = []

        else:

            new_last, new_key = data[0].pop()

            used[new_key] = 1

            self.siz -= 1

        return new_last, new_key



    def __len__(self):

        return self.siz



import sys

readline = sys.stdin.readline

write = sys.stdout.write



N, M, s = list(map(int, readline().split()))

G = [[] for i in range(N)]

for i in range(M):

    a, b, c = list(map(int, readline().split()))

    G[a].append((b, c))



INF = 10**18

def dijkstra(N, G, s):

    que = RadixHeap(N, 10**9 + 1)



    dist = [INF]*N

    dist[s] = 0

    que.push(0, s)

    while que:

        cost, v = que.pop()

        if dist[v] < cost:

            continue

        for w, c in G[v]:

            if cost + c < dist[w]:

                dist[w] = r = cost + c

                que.push(r, w)

    return dist



dist = dijkstra(N, G, s)

for c in dist:

    write("INF\n" if c == INF else "%d\n" % c)

from heapq import heappush, heappop

V, E, r = list(map(int, input().split()))
g = [[] for i in range(V)]
for i in range(E):
    s, t, d = list(map(int, input().split()))
    g[s].append((t, d))
INF = 10**10
dist = [INF] * V
que = [(0, r)]
dist[r] = 0
while que:
    c, v = heappop(que)
    if dist[v] < c:
        continue
    for t, cost in g[v]:
        if dist[v] + cost < dist[t]:
            dist[t] = dist[v] + cost
            heappush(que, (dist[t], t))
for i in range(V):
    print(dist[i] if dist[i] < INF else "INF")

class RadixHeap:
    __slots__ = ["data", "last", "siz", "used"]
    # (max_key - min_key) <= C
    def __init__(self, N, C):
        self.data = [[] for i in range(C.bit_length() + 1)]
        self.last = self.siz = 0
        self.used = [0] * N

    def push(self, x, key):
        # assert self.last <= x
        self.siz += 1
        self.data[(x ^ self.last).bit_length()].append((x, key))

    def pop(self):
        data = self.data
        used = self.used
        # assert self.siz > 0
        if not data[0]:
            i = 1
            while not data[i]:
                i += 1
            d = data[i]
            new_last, new_key = min(d)
            used[new_key] = 1
            for val in d:
                x, key = val
                if used[key]:
                    self.siz -= 1
                    continue
                data[(x ^ new_last).bit_length()].append(val)
            self.last = new_last
            data[i] = []
        else:
            new_last, new_key = data[0].pop()
            used[new_key] = 1
            self.siz -= 1
        return new_last, new_key

    def __len__(self):
        return self.siz


import sys

readline = sys.stdin.readline
write = sys.stdout.write
N, M, s = list(map(int, readline().split()))
G = [[] for i in range(N)]
for i in range(M):
    a, b, c = list(map(int, readline().split()))
    G[a].append((b, c))
INF = 10**18


def dijkstra(N, G, s):
    que = RadixHeap(N, 10**9 + 1)
    dist = [INF] * N
    dist[s] = 0
    que.push(0, s)
    while que:
        cost, v = que.pop()
        if dist[v] < cost:
            continue
        for w, c in G[v]:
            if cost + c < dist[w]:
                dist[w] = r = cost + c
                que.push(r, w)
    return dist


dist = dijkstra(N, G, s)
for c in dist:
    write("INF\n" if c == INF else "%d\n" % c)

-from heapq import heappush, heappop +class RadixHeap: +    __slots__ = ["data", "last", "siz", "used"] +    # (max_key - min_key) <= C +    def __init__(self, N, C): +        self.data = [[] for i in range(C.bit_length() + 1)] +        self.last = self.siz = 0 +        self.used = [0] * N -V, E, r = list(map(int, input().split())) -g = [[] for i in range(V)] -for i in range(E): -    s, t, d = list(map(int, input().split())) -    g[s].append((t, d)) -INF = 10**10 -dist = [INF] * V -que = [(0, r)] -dist[r] = 0 -while que: -    c, v = heappop(que) -    if dist[v] < c: -        continue -    for t, cost in g[v]: -        if dist[v] + cost < dist[t]: -            dist[t] = dist[v] + cost -            heappush(que, (dist[t], t)) -for i in range(V): -    print(dist[i] if dist[i] < INF else "INF") +    def push(self, x, key): +        # assert self.last <= x +        self.siz += 1 +        self.data[(x ^ self.last).bit_length()].append((x, key)) + +    def pop(self): +        data = self.data +        used = self.used +        # assert self.siz > 0 +        if not data[0]: +            i = 1 +            while not data[i]: +                i += 1 +            d = data[i] +            new_last, new_key = min(d) +            used[new_key] = 1 +            for val in d: +                x, key = val +                if used[key]: +                    self.siz -= 1 +                    continue +                data[(x ^ new_last).bit_length()].append(val) +            self.last = new_last +            data[i] = [] +        else: +            new_last, new_key = data[0].pop() +            used[new_key] = 1 +            self.siz -= 1 +        return new_last, new_key + +    def __len__(self): +        return self.siz + + +import sys + +readline = sys.stdin.readline +write = sys.stdout.write +N, M, s = list(map(int, readline().split())) +G = [[] for i in range(N)] +for i in range(M): +    a, b, c = list(map(int, readline().split())) +    G[a].append((b, c)) +INF = 10**18 + + +def dijkstra(N, G, s): +    que = RadixHeap(N, 10**9 + 1) +    dist = [INF] * N +    dist[s] = 0 +    que.push(0, s) +    while que: +        cost, v = que.pop() +        if dist[v] < cost: +            continue +        for w, c in G[v]: +            if cost + c < dist[w]: +                dist[w] = r = cost + c +                que.push(r, w) +    return dist + + +dist = dijkstra(N, G, s) +for c in dist: +    write("INF\n" if c == INF else "%d\n" % c)