#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define all(c) begin(c), end(c)
#define range(i,a,b) for(int i = a; i < (int)(b); i++)
#define rep(i,b) range(i,0,b)
#define eb emplace_back
typedef long long ll;
auto const inf = numeric_limits<ll>::max()/4;

using Weight = ll;
using Capacity = int;
struct Edge {
    int src, dst; Weight weight;
    Edge(int s, int d, int w) : src(s), dst(d), weight(w) {}
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;
using Array = vector<Weight>;
using Matrix = vector<Array>;

vector<Weight> dijkstra(const Graph &g, int s){
    const Weight inf = numeric_limits<Weight>::max()/4;
    typedef tuple<Weight,int> State;
    priority_queue<State> q;
    vector<Weight> dist(g.size(), inf);
    dist[s] = 0; q.emplace(0,s);
    while (q.size()) {
        Weight d; int v;
        tie(d,v) = q.top(); q.pop(); d *= -1;
        /* if(v == t) return d; */
        if (dist[v] < d) continue;
        for(auto & e : g[v]){
            if (dist[e.dst] > dist[v] + e.weight) {
                dist[e.dst] = dist[v] + e.weight;
                q.emplace(-dist[e.dst], e.dst);
            }
        }
    }
    return dist;
}


int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);
    int V,E,r;
    while(cin >> V >> E >> r){
        Graph g(V);
        rep(i,E){
            int a,b,c;
            cin >> a >> b >> c;
            g[a].eb(a,b,c);
        }
        vector<Weight> dist = dijkstra(g,r);
        for(int i = 0; i < (int)dist.size(); i++){
            if(dist[i] == inf) cout << "INF";
            else cout << dist[i];
            cout << endl;
        }
    }
}

#include <bits/stdc++.h>
using namespace std;
#define REP(i,x) for(int i = 0;i < x;++i)
#define FOR(i,x,y) for(int i = x;i < y;++i)
#define ALL(a) a.begin(),a.end()
using ll = long long;

int v,e,r;
struct edge
{
    int to,cost;
};
vector<edge>graph[114514];

using P = pair<int,int>;
const int INF = 1234567890;
int dist[114514];
void dijkstra()
{
    fill(dist,dist+114514,INF);
    dist[r] = 0;
    priority_queue<P,vector<P>,greater<P>>que;
    que.push({0,r});
    while(!que.empty())
    {
        P p = que.top(); que.pop();
        int ds = p.first;
        int now = p.second;
        if(dist[now] < ds)continue;
        for(auto& ed : graph[now])
        {
            if(dist[ed.to] > dist[now] + ed.cost)
            {
                dist[ed.to] = dist[now] + ed.cost;
                que.push({dist[ed.to],ed.to});
            }
        }
    }
}

int main()
{
    cin >> v >> e >> r;
    REP(i,e)
    {
        int s,t,d;
        cin >> s >> t >> d;
        graph[s].push_back({t,d});
    }
    dijkstra();
    REP(i,v)
    {
        int dd = dist[i];
        if(dd >= INF)
        {
            cout << "INF" << endl;
        }
        else
        {
            cout << dd << endl;
        }
    }
    return 0;
}