#include <bits/stdc++.h>   using namespace std;   const long long maxN = 1e5 + 5;   const long long mod = 1e18 + 5;   struct makeEdge {     long long weight;     long long left;     long long right;     long long vertex;   };   struct makeEdge piece;   vector<makeEdge> query2;   vector<makeEdge> query3;   long long start;   long long cnt;   long long n;   long long a[maxN];   long long tree[maxN * 4];   long long l[maxN * 4];   long long r[maxN * 4];   long long ans[maxN];   vector<pair<long long, long long>> vc[maxN * 10];   void direct(long long i, long long j) {     vc[i].push_back(pair<long long, long long>(0, j));   }   void newpath(long long i, long long j, long long anewweight) {     vc[i].push_back(pair<long long, long long>(anewweight, j));   }   void buildTree(long long node, long long left, long long right) {     l[node] = left;     r[node] = right;     if (left == right) return;     long long mid = (left + right) / 2;     buildTree(node * 2, left, mid);     buildTree(node * 2 + 1, mid + 1, right);   }   void update2(long long node, long long left, long long right, long long wei,                long long emit) {     if (l[node] == left && r[node] == right) {       newpath(emit, ((node) + n), wei);       return;     }     if (left > r[node * 2]) {       update2(node * 2 + 1, left, right, wei, emit);       return;     }     if (right < l[node * 2 + 1]) {       update2(node * 2, left, right, wei, emit);       return;     }     update2(node * 2, left, r[node * 2], wei, emit);     update2(node * 2 + 1, l[node * 2 + 1], right, wei, emit);     return;   }   void update3(long long node, long long left, long long right, long long wei,                long long emit) {     if (l[node] == left && r[node] == right) {       newpath(((node) + n * 5 - 1), emit, wei);       return;     }     if (left > r[node * 2]) {       update3(node * 2 + 1, left, right, wei, emit);       return;     }     if (right < l[node * 2 + 1]) {       update3(node * 2, left, right, wei, emit);       return;     }     update3(node * 2, left, r[node * 2], wei, emit);     update3(node * 2 + 1, l[node * 2 + 1], right, wei, emit);     return;   }   void solve() {     for (long long i = 1; i <= n; i++) {       ans[i] = mod;     }     priority_queue<pair<long long, long long>, vector<pair<long long, long long>>,                    greater<pair<long long, long long>>>         pq;     pq.push(pair<long long, long long>(0, start));     ans[start] = 0;     while (!pq.empty()) {       pair<long long, long long> front = pq.top();       pq.pop();       long long node = front.second;       long long dist = front.first;       if (dist != ans[node]) continue;       for (long long i = 0; i < vc[node].size(); i++) {         long long child = vc[node][i].second;         if (dist + vc[node][i].first < ans[child]) {           ans[child] = dist + vc[node][i].first;           pq.push(pair<long long, long long>(ans[child], child));         }       }     }   }   long long t, x, y, www;   signed main() {     cin >> n;     long long o;     cin >> o;     cin >> start;     buildTree(1, 1, n);     while (o--) {       cin >> t;       if (t == 1) {         cin >> x >> y >> www;         vc[x].push_back(pair<long long, long long>(www, y));       } else {         cin >> piece.vertex;         cin >> piece.left;         cin >> piece.right;         cin >> piece.weight;         if (t == 2) query2.push_back(piece);         if (t == 3) query3.push_back(piece);       }     }     buildTree(1, 1, n);     for (long long i = 1; i <= n * 4 - 1; i++) {       if (l[i] == 0) continue;       if (l[i] == r[i])         direct(((i) + n), l[i]);       else {         direct(((i) + n), ((i * 2) + n));         direct(((i) + n), ((i * 2 + 1) + n));       }     }     for (long long i = 0; i < query2.size(); i++) {       update2(1, query2[i].left, query2[i].right, query2[i].weight,               query2[i].vertex);     }     buildTree(1, 1, n);     for (long long i = 1; i <= n * 4 - 1; i++) {       if (l[i] == 0) continue;       if (l[i] == r[i])         direct(l[i], ((i) + n * 5 - 1));       else {         direct(((i * 2 + 1) + n * 5 - 1), ((i) + n * 5 - 1));         direct(((i * 2) + n * 5 - 1), ((i) + n * 5 - 1));       }     }     for (long long i = 0; i < query3.size(); i++) {       update3(1, query3[i].left, query3[i].right, query3[i].weight,               query3[i].vertex);     }     n = n * 9 - 2;     solve();     n = (n + 2) / 9;     for (long long i = 1; i <= n; i++) {       if (ans[i] == mod)         cout <<  -1  ;       else         cout << ans[i] <<    ;     }   }