#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define spair(p) cout<<#p<<": "<<p.fi<<" "<<p.se<<endl
#define sar(a,n) cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl
#define svec(v) cout<<#v<<":";rep(pachico,v.size())cout<<" "<<v[pachico];cout<<endl
#define svecp(v) cout<<#v<<":";each(pachico,v)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl
#define sset(s) cout<<#s<<":";each(pachico,s)cout<<" "<<pachico;cout<<endl
#define smap(m) cout<<#m<<":";each(pachico,m)cout<<" {"<<pachico.first<<":"<<pachico.second<<"}";cout<<endl

using namespace std;

typedef pair<int,int> P;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<P> vp;
typedef vector<string> vs;

const int MAX_N = 100005;

#define impl(x, last) x == last ? 0 : 31 - __builtin_clz(x ^ last)

// class RadixHeap{
// private:
//     int last, size_;
//     vector<P> bucket_[32];
// public:
//     RadixHeap() : last(0), size_(0){}
//     void push(int x, int val){
//         size_++, bucket_[impl(x, last)].emplace_back(x, val);
//     }
//     P pop(bool flag = true){
//         if(bucket_[0].empty()){
//             int id = 1;
//             while(bucket_[id].empty()) id++;
//             last = min_element(bucket_[id].begin(), bucket_[id].end())->first;
//             for(auto val : bucket_[id]){
//                 bucket_[impl(val.first, last)].push_back(val);
//             }
//             bucket_[id].clear();
//         }
//         P res = bucket_[0].back();
//         if(flag) size_--, bucket_[0].pop_back();
//         return res;
//     }
//     P top(){
//         return pop(false);
//     }
//     bool empty(){
//         return !size_;
//     }
// };

int bsr(uint x) {
    if (x == 0) return -1;
    return 31-__builtin_clz(x);
}

template<class C>
struct RadixHeap {
    typedef pair<uint, C> P;
    vector<P> v[33];
    uint last, sz;
    RadixHeap() {
        last = sz = 0;
    }
    void push(uint x, C p) {
        assert(last <= x);
        sz++;
        v[bsr(x^last)+1].push_back(P(x, p));
    }
    void push(P p) {
        push(p.first, p.second);
    }
    P top() {
        return pop(false);
    }
    P pop(bool f = true) {
        assert(sz);
        if (!v[0].size()) {
            int i = 1;
            while (!v[i].size()) i++;
            last = min_element(v[i].begin(), v[i].end())->first;
            for (P p: v[i]) {
                v[bsr(p.first^last)+1].push_back(p);
            }
            v[i].clear();
        }
        P r = v[0].back();
        if (f) {
            sz--;
            v[0].pop_back();
        }
        return r;
    }
    int size() {
        return sz;
    }
    bool empty() {
        return sz == 0;
    }
    void clear() {
        last = sz = 0;
        for (int i = 0; i < 33; i++) {
            v[i].clear();
        }
    }
};

struct edge{
    int to, cost;
};

vector<edge> G[MAX_N];
int d[MAX_N];
void solve(int s){
    memset(d, INF, sizeof(d));
    RadixHeap<int> que;
    d[s] = 0;
    que.push(0, s);
    while(!que.empty()){
        P p = que.top();
        que.pop();
        int v = p.second;
        if(d[v] < p.first) continue;
        for(auto& e : G[v]){
            if(d[e.to] > d[v] + e.cost){
                d[e.to] = d[v] + e.cost;
                que.push(d[e.to], e.to);
            }
        }
    }
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m, s;
    cin >> n >> m >> s;
    rep(i,m){
        int a,b,c;
        cin >> a >> b >> c;
        G[a].pb((edge){b, c});
    }
    solve(s);
    rep(i,n){
        if(d[i] == INF){
            cout << "INF\n";
        }else{
            cout << d[i] << "\n";
        }
    }
    return 0;
}



Measured memory_bytes: 13416