#include <bits/stdc++.h>
const long long MAXN = 7e5;
long long get_int() {
  long long x = 0, y = 1;
  char ch = getchar();
  while (!isdigit(ch) && ch != '-') ch = getchar();
  if (ch == '-') y = -1, ch = getchar();
  while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
  return x * y;
}
long long n, rank[MAXN << 4], lSon[MAXN], rSon[MAXN], vis[MAXN], cnt = 1;
class Edge {
 public:
  long long next, to, value;
} edges[MAXN << 2];
long long head[MAXN << 2], eNum;
void addEdge(long long from, long long to, long long value) {
  edges[eNum] = (Edge){head[from], to, value};
  head[from] = eNum++;
}
void buildTree1(long long now, long long lRange = 0, long long rRange = n) {
  if (lRange + 1 == rRange) {
    rank[lRange] = now;
    return;
  }
  long long mid = (lRange + rRange) / 2;
  lSon[now] = cnt++;
  rSon[now] = cnt++;
  addEdge(now, lSon[now], 0);
  addEdge(now, rSon[now], 0);
  buildTree1(lSon[now], lRange, mid);
  buildTree1(rSon[now], mid, rRange);
}
void buildTree2(long long now, long long lRange = 0, long long rRange = n) {
  if (lRange + 1 == rRange) {
    return;
  }
  long long mid = (lRange + rRange) / 2;
  if (lRange == mid - 1) {
    lSon[now] = rank[lRange];
    addEdge(rank[lRange], now, 0);
  } else {
    lSon[now] = cnt++;
    addEdge(lSon[now], now, 0);
  }
  if (mid == rRange - 1) {
    rSon[now] = rank[mid];
    addEdge(rank[mid], now, 0);
  } else {
    rSon[now] = cnt++;
    addEdge(rSon[now], now, 0);
  }
  buildTree2(lSon[now], lRange, mid);
  buildTree2(rSon[now], mid, rRange);
}
void modify(long long now, long long from, long long toL, long long toR,
            long long value, long long mode, long long lRange = 0,
            long long rRange = n) {
  if (toR <= lRange || rRange <= toL) return;
  if (toL <= lRange && rRange <= toR) {
    if (mode == 2) addEdge(from, now, value);
    if (mode == 3) addEdge(now, from, value);
    return;
  }
  long long mid = (lRange + rRange) / 2;
  modify(lSon[now], from, toL, toR, value, mode, lRange, mid);
  modify(rSon[now], from, toL, toR, value, mode, mid, rRange);
}
std::pair<long long, long long> heap[MAXN];
long long dis[MAXN], heapSize;
long long cmp(const std::pair<long long, long long>& a,
              const std::pair<long long, long long>& b) {
  return a.second >= b.second;
}
void push(long long rank, long long value) {
  heap[heapSize++] = std::make_pair(rank, value);
  std::push_heap(heap, heap + heapSize, cmp);
}
long long pop() {
  std::pop_heap(heap, heap + heapSize, cmp);
  return heap[--heapSize].first;
}
signed main() {
  memset(head, -1, sizeof(head));
  n = get_int();
  long long q = get_int(), s = get_int() - 1;
  buildTree1(0);
  long long root2 = cnt;
  buildTree2(cnt++);
  while (q--) {
    long long mode = get_int();
    if (mode == 1) {
      long long from = get_int() - 1, to = get_int() - 1, value = get_int();
      addEdge(rank[from], rank[to], value);
    } else if (mode == 2) {
      long long from = get_int() - 1, toL = get_int() - 1, toR = get_int(),
                value = get_int();
      modify(0, rank[from], toL, toR, value, 2);
    } else if (mode == 3) {
      long long from = get_int() - 1, toL = get_int() - 1, toR = get_int(),
                value = get_int();
      modify(root2, rank[from], toL, toR, value, 3);
    }
  }
  memset(dis, 0x3f, sizeof(dis));
  dis[rank[s]] = 0;
  push(rank[s], 0);
  while (heapSize != 0) {
    long long now = pop();
    vis[now] = false;
    for (long long i = head[now]; i != -1; i = edges[i].next) {
      long long to = edges[i].to, value = edges[i].value;
      if (dis[now] + value >= dis[to]) continue;
      dis[to] = dis[now] + value;
      if (vis[to] == false) {
        vis[to] = true;
        push(to, dis[to]);
      }
    }
  }
  for (long long i = 0; i < n; i++) {
    if (dis[rank[i]] == 0x3f3f3f3f3f3f3f3f)
      std::cout << -1 << ' ';
    else {
      std::cout << dis[rank[i]] << ' ';
    }
  }
  return 0;
}
