#include <bits/stdc++.h>   using namespace std;   priority_queue<pair<long long, int>, vector<pair<long long, int> >,                  greater<pair<long long, int> > >       q;   struct node {     int left, right, num[3];   } tree[4 * 100010];   struct NODE {     int begin, end, value, next;   } edge[50 * 100010 + 10];   int cnt, Head[2 * 4 * 100010 + 10], lcc[3], SIZE, cc[3][100010];   long long dis[2 * 4 * 100010 + 10];   int read() {     int s = 0, fh = 1;     char ch = getchar();     while (ch <  0  || ch >  9 ) {       if (ch ==  - ) fh = -1;       ch = getchar();     }     while (ch >=  0  && ch <=  9 ) {       s = s * 10 + (ch -  0 );       ch = getchar();     }     return s * fh;   }   void addedge(int bb, int ee, int vv) {     edge[++cnt].begin = bb;     edge[cnt].end = ee;     edge[cnt].value = vv;     edge[cnt].next = Head[bb];     Head[bb] = cnt;   }   void addedge1(int bb, int ee, int vv) {     addedge(bb, ee, vv);     addedge(ee, bb, vv);   }   void Build(int k, int l, int r) {     tree[k].left = l;     tree[k].right = r;     tree[k].num[1] = ++SIZE;     tree[k].num[2] = ++SIZE;     if (l == r) {       addedge(tree[k].num[1], tree[k].num[2], 0);       return;     }     int mid = (l + r) / 2;     Build(k * 2, l, mid);     Build(k * 2 + 1, mid + 1, r);     addedge(tree[k].num[1], tree[k * 2].num[1], 0);     addedge(tree[k].num[1], tree[k * 2 + 1].num[1], 0);     addedge(tree[k * 2].num[2], tree[k].num[2], 0);     addedge(tree[k * 2 + 1].num[2], tree[k].num[2], 0);   }   void Find(int k, int ql, int qr, int F) {     if (ql <= tree[k].left && tree[k].right <= qr) {       cc[F][++lcc[F]] = tree[k].num[F];       return;     }     int mid = (tree[k].left + tree[k].right) / 2;     if (qr <= mid)       Find(k * 2, ql, qr, F);     else if (ql > mid)       Find(k * 2 + 1, ql, qr, F);     else {       Find(k * 2, ql, mid, F);       Find(k * 2 + 1, mid + 1, qr, F);     }   }   void dijkstra(int start) {     int i, u, v;     for (i = 1; i <= SIZE; i++) dis[i] = 1LL << 60;     dis[start] = 0LL;     q.push(make_pair(dis[start], start));     while (!q.empty()) {       u = q.top().second;       q.pop();       for (i = Head[u]; i != -1; i = edge[i].next) {         v = edge[i].end;         if (dis[v] > dis[u] + (long long)edge[i].value) {           dis[v] = dis[u] + (long long)edge[i].value;           q.push(make_pair(dis[v], v));         }       }     }   }   int main() {     int N, Q, S, i, zs, s1, s2, s3, s4, j;     N = read();     Q = read();     S = read();     memset(Head, -1, sizeof(Head));     cnt = 1;     SIZE = 0;     Build(1, 1, N);     for (i = 1; i <= Q; i++) {       zs = read();       if (zs == 1) {         s1 = read();         s2 = read();         s3 = read();         lcc[1] = lcc[2] = 0;         Find(1, s1, s1, 2);         Find(1, s2, s2, 1);         addedge(cc[2][1], cc[1][1], s3);       } else if (zs == 2) {         s1 = read();         s2 = read();         s3 = read();         s4 = read();         lcc[1] = lcc[2] = 0;         Find(1, s1, s1, 2);         Find(1, s2, s3, 1);         for (j = 1; j <= lcc[1]; j++) addedge(cc[2][1], cc[1][j], s4);       } else {         s1 = read();         s2 = read();         s3 = read();         s4 = read();         lcc[1] = lcc[2] = 0;         Find(1, s2, s3, 2);         Find(1, s1, s1, 1);         for (j = 1; j <= lcc[2]; j++) addedge(cc[2][j], cc[1][1], s4);       }     }     lcc[2] = 0;     Find(1, S, S, 2);     dijkstra(cc[2][1]);     for (i = 1; i <= N; i++) {       lcc[2] = 0;       Find(1, i, i, 2);       printf( %lld  , dis[cc[2][1]] == 1LL << 60 ? -1LL : dis[cc[2][1]]);     }     return 0;   }