#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <algorithm>

#define int long long
#define MOD7 1000000007
#define MOD9 1000000009

#define rep(i, n) for (int i = 0; i < (n); i++)
#define all(a) (a).begin(), (a).end()

using namespace std;

int nextInt() {int a; cin >> a; return a;}
char nextChar() {char a; cin >> a; return a;}
double nextDouble() {double a; cin >> a; return a;}
string nextString() {string a; cin >> a; return a;}

void inputVector(vector<int> &v, int &n) {rep(i,n){v.push_back(nextInt());}}
void inputVector(vector<double> &v, int &n) {rep(i,n){v.push_back(nextDouble());}}
void inputVector(vector<string> &v, int &n) {rep(i,n){v.push_back(nextString());}}

class Graph {
private:
    // ?????\?????¨??????????????±
    struct QInfo {
	int nodeNum;    // ???????????????
	long long dist;	    // ?????¢

	// ?????????????????????
	QInfo(int argNum, long long argDist) {
	    nodeNum = argNum;
	    dist = argDist;
	}
	// ??????????????????????????????
	bool operator<(const QInfo& a) const {
	    return dist > a.dist;
	}
    };

public:
    // ??¨??????????????±
    struct Edge {
	int next;	    	// ????§????????????????
	long long weight;	// ??¨???????????????

	// ?????????????????????
	Edge() {
	    next = -1;
	    weight = 0;
	}
	Edge(int argNext, int argWeight) {
	    next = argNext;
	    weight = argWeight;
	}
    };
    // ?????????????????±
    struct Node {
	long long dist;	    // ????????????????????¨?????¢
	vector<Edge> edge;  // ??\?¶?????????¨???????????±
    };

    // ??????????????????
    vector<Node> node;

    /*
    /  ?????????????????????
    /  - ?????°??§????????????????????°????????????????????????
    */
    Graph(int num) {
	for (int i = 0; i < num; i++) {
	    node.push_back(Node());
	}
    }

    /*
    /  addNode
    /  - ??????????????????
    /   num : ?????????????????°
    */
    void addNode(int num) {
	for (int i = 0; i < num; i++) {
	    node.push_back(Node());
	}
    }

    /*
    /  makeEdge
    /  - ??¨???????????????
    /   prevNode : ??\?¶??????????????????????
    /   nextNode : ??\?¶??????????????????????
    /   weight   : ??¨???????????????
    /   flagBidirect : ??????????????¨??????????????????
    */
    void makeEdge(int prevNode, int nextNode, long long weight, bool flagBidirect) {
	node[prevNode].edge.push_back(Edge(nextNode, weight));
	if (flagBidirect) {
	    node[nextNode].edge.push_back(Edge(prevNode, weight));
	}
    }

    /*
    /  deleteEdge
    /  - ??¨?????????????????????
    /   prevNode : ??\?¶??????????????????????
    /   nextNode : ??\?¶??????????????????????
    /   flagBidirect : ????????????????????¨????????????
    /   ????????? : ?????????????????????????????????
    */
    bool deleteEdge(int prevNode, int nextNode, bool flagBidirect) {
	bool flagDelete = false;
	vector<Edge>::iterator it;
	// prevNode -> nextNode ?????????
	for (it = node[prevNode].edge.begin(); it != node[prevNode].edge.end(); it++) {
	    if ((*it).next == nextNode) {
		node[prevNode].edge.erase(it);
		flagDelete = true;
	    }
	}
	
	if (!flagBidirect) return flagDelete;

	// nextNode -> prevNode ?????????
	for (it = node[nextNode].edge.begin(); it != node[nextNode].edge.end(); it++) {
	    if ((*it).next == prevNode) {
		node[nextNode].edge.erase(it);
		flagDelete = true;
	    }
	}

	return flagDelete;
    }

    /*
    /  changeWeight
    /  - ??¨???????????????????????´??????
    /   prevNode : ????§??????????????????????
    /   nextNode : ????§??????????????????????
    /   weight   : ?????´????????????
    /   flagBidirect : ????????????????????¨????????????
    /   ????????? : ?????´???????????????????????????
    */
    bool changeWeight(int prevNode, int nextNode, long long weight, bool flagBidirect) {
	bool flagChange = false;
	vector<Edge>::iterator it;
	for (it = node[prevNode].edge.begin(); it != node[prevNode].edge.end(); it++) {
	    if ((*it).next == nextNode) {
		(*it).weight = weight;
		flagChange = true;
	    }
	}

	if (!flagBidirect) return flagChange;

	for (it = node[nextNode].edge.begin(); it != node[nextNode].edge.end(); it++) {
	    if ((*it).next == prevNode) {
		(*it).weight = weight;
		flagChange = true;
	    }
	}

	return flagChange;
    }

    /*
    /  dijkstra
    /  - ???????????????????????§????????????????????¢????±???????
    /   startNode : ???????????????????????????
    /   endNode   : ??´????????????????????????
    /   ????????? : 2??????????????¢
    */
    int dijkstra(int startNode, int endNode) {

	// ?????¢?????????
	for (int i = 0; i < node.size(); i++) {
	    node[i].dist = LLONG_MAX;
	}
	node[startNode].dist = 0;

	priority_queue<QInfo> q;
	set<int> inq;
	q.push(QInfo(startNode, 0));
	inq.insert(startNode);
	while (!q.empty()) {
	    QInfo now = q.top(); q.pop();
	    Node nowNode = node[now.nodeNum];
	    inq.erase(now.nodeNum);

	    for (vector<Edge>::iterator it = nowNode.edge.begin(); it != nowNode.edge.end(); it++) {
		int nextNode = (*it).next;
		if (nowNode.dist + (*it).weight < node[nextNode].dist) {
		    // ?????¢?????´??°
		    node[nextNode].dist = nowNode.dist + (*it).weight;
		    
		    // ?????\????????\??£??????????????°push
		    if (inq.find(nextNode) == inq.end()) {
			q.push(QInfo(nextNode, node[nextNode].dist));
			inq.insert(startNode);
		    }
		}
	    }
	}

	return node[endNode].dist;
    }
};

signed main() {
	int V, E, r;
	cin >> V >> E >> r;

	auto g = Graph(V);

	rep(i, E) {
		int s, t, d;
		cin >> s >> t >> d;
		g.makeEdge(s, t, d, false);
	}

	g.dijkstra(r, 0);

	rep(i, V) {
		int dist = g.node[i].dist;
		if (dist == LLONG_MAX) {
			cout << "INF" << endl;
		} else {
			cout << dist << endl;
		}
	}

	return 0;
}

Measured memory_bytes: 20312