// Slower C++ solution:
#include <bits/stdc++.h>

#define chmin(a, b) ((a)=min((a), (b)))

#define chmax(a, b) ((a)=max((a), (b)))

#define fs first

#define sc second

#define eb emplace_back

using namespace std;



typedef long long ll;

typedef pair<int, int> P;

typedef tuple<int, int, int> T;



const ll MOD=1e9+7;

const ll INF=1e18;



int dx[]={1, -1, 0, 0};

int dy[]={0, 0, 1, -1};



vector<vector<P>> g(100010);

vector<ll> dist(100010, INF);



void dijkstra(int s){

    priority_queue<P, vector<P>, greater<P>> que;

    dist[s]=0;

    que.push(P(0, s));



    while(!que.empty()){

        P p=que.top(); que.pop();

        ll pcost=p.first, pv=p.second;

        if(dist[pv] < pcost) continue;



        for(int i=0; i<g[pv].size(); i++){

            P p2=g[pv][i];

            ll nv=p2.first, ncost=p2.second;

            if(dist[nv] > dist[pv] + ncost){

                dist[nv] = dist[pv] + ncost;

                que.push(P(dist[nv], nv));

            }

        }

    }

}



int main(){

    int v, e, r; cin>>v>>e>>r;

    for(int i=0; i<e; i++){

        int s, t, d; cin>>s>>t>>d;

        g[s].eb(P(t, d));

    }



    dijkstra(r);



    for(int i=0; i<v; i++){

        if(dist[i]!=INF) cout << dist[i] << endl;

        else cout << "INF" << endl;

    }

}


// Faster C++ solution for the same problem (measured speedup: 4.427210891636492x):
#pragma GCC optimize("O3")

#include <iostream>

#include <iomanip>

#include <cstdio>

#include <string>

#include <cstring>

#include <deque>

#include <list>

#include <queue>

#include <stack>

#include <vector>

#include <utility>

#include <algorithm>

#include <map>

#include <set>

#include <complex>

#include <cmath>

#include <limits>

#include <cfloat>

#include <climits>

#include <ctime>

#include <cassert>

#include <numeric>

#include <fstream>

#include <functional>

#include <bitset>

using namespace std;



using ll = long long;

using P = pair<int, int>;

using T = tuple<int, int, int>;



template <class T> inline T chmax(T &a, const T b) {return a = (a < b) ? b : a;}

template <class T> inline T chmin(T &a, const T b) {return a = (a > b) ? b : a;}



constexpr int MOD = 1e9 + 7;

constexpr int inf = 1e9;

constexpr long long INF = 1e18;

constexpr double pi = acos(-1);

constexpr double EPS = 1e-10;



int dx[] = {1, 0, -1, 0};

int dy[] = {0, 1, 0, -1};



vector<int> dijkstra(int s, vector<vector<P>> &G){

    int n = G.size();

    vector<int> dist(n, inf);

    priority_queue<P, vector<P>, greater<P>> que;

    dist[s] = 0;

    que.emplace(0, s);



    while(que.size()){

        int ccost, cv;

        tie(ccost, cv) = que.top(); que.pop();



        if(dist[cv] < ccost) continue;



        for(auto nxt : G[cv]){

            int nv, ncost;

            tie(nv, ncost) = nxt;

            

            if(dist[cv] + ncost < dist[nv]){

                dist[nv] = dist[cv] + ncost;

                que.emplace(dist[nv], nv);

            }

        }

    }



    return dist;

}



int main(){

    cin.tie(0);

    ios::sync_with_stdio(false);



    int v, e, r; cin>>v>>e>>r;

    vector<vector<P>> G(v);

    for(int i=0; i<e; i++){

        int s, t, d; cin>>s>>t>>d;

        G[s].emplace_back(t, d);

    }



    auto dist = dijkstra(r, G);



    for(int i=0; i<v; i++){

        if(dist[i] == inf) cout << "INF" << endl;

        else cout << dist[i] << endl;

    }



    return 0;

}