#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast,inline")
using namespace std;
namespace Base {
inline char gc(void) {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
template <class T>
inline void read(T &x) {
  T flag = (T)1;
  x = 0;
  static char ch = getchar();
  for (; ch > '9' || ch < '0'; ch = getchar()) flag = ch == '-' ? -1 : 1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = (x << 1) + (x << 3) + (ch & 15);
  x *= flag;
  return;
}
inline void readstr(string &x) {
  x = "";
  static char ch;
  while (isspace(ch = getchar()))
    ;
  while (x += ch, !isspace(ch = getchar()))
    ;
}
inline void readstr(char *s) {
  do *s = getchar();
  while ((*s == ' ') || (*s == '\n') || (*s == '\r'));
  do *(++s) = getchar();
  while ((~*s) && (*s != ' ') && (*s != '\n') && (*s != '\r'));
  *s = 0;
  return;
}
inline void printstr(string x, int num = 0, char ch = '\n') {
  for (int i = num; i < x.size(); ++i) putchar(x[i]);
  putchar(ch);
}
inline void readch(char &x) {
  while (isspace(x = getchar()))
    ;
}
char pf[100000], *o1 = pf, *o2 = pf + 100000;
template <class T>
inline void println(T x, char c = '\n') {
  if (x < 0)
    (o1 == o2 ? fwrite(pf, 1, 100000, stdout), *(o1 = pf)++ = 45 : *o1++ = 45),
        x = -x;
  static char s[15], *b;
  b = s;
  if (!x) *b++ = 48;
  for (; x; *b++ = x % 10 + 48, x /= 10)
    ;
  for (; b-- != s; (o1 == o2          ? fwrite(pf, 1, 100000, stdout),
                    *(o1 = pf)++ = *b : *o1++ = *b))
    ;
  (o1 == o2 ? fwrite(pf, 1, 100000, stdout), *(o1 = pf)++ = c : *o1++ = c);
}
template <class T>
inline void write(T x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar(x % 10 + '0');
  return;
}
template <class T>
inline void writeln(T x) {
  write(x);
  puts("");
}
template <class T>
inline void writeln(T x, char c) {
  write(x);
  putchar(c);
}
template <class T>
inline void writeln(char c, T x) {
  putchar(c);
  write(x);
}
template <class T>
inline void chkmax(T &x, const T y) {
  x > y ? x = x : x = y;
}
template <class T>
inline void chkmin(T &x, const T y) {
  x < y ? x = x : x = y;
}
template <class T>
inline T max(const T &x, const T &y, const T &z) {
  return x > y ? (x > z ? x : z) : (y > z ? y : z);
}
inline void file(string str) {
  freopen((str + ".in").c_str(), "r", stdin);
  freopen((str + ".out").c_str(), "w", stdout);
}
struct Vector {
  double x, y;
  Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}
  inline Vector Vary(void) { return Vector(x, -y); }
  inline bool operator<(const Vector &rhs) const {
    return x == rhs.x ? y < rhs.y : x < rhs.x;
  }
  inline Vector operator-(const Vector &rhs) const {
    return Vector(x - rhs.x, y - rhs.y);
  }
  inline Vector operator+(const Vector &rhs) const {
    return Vector(x + rhs.x, y + rhs.y);
  }
  inline Vector operator*(const double &rhs) const {
    return Vector(x * rhs, y * rhs);
  }
  inline Vector operator/(const double &rhs) const {
    return Vector(x / rhs, y / rhs);
  }
  inline Vector operator*(const Vector &rhs) const {
    return Vector(x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x);
  }
};
}  // namespace Base
using namespace Base;
const int Maxt = 3e5 + 5;
const int Maxm = 2e6 + 5;
int n, q, s, cnt = 0, head[Maxt], ver[Maxm], nxt[Maxm], edge[Maxm];
inline void AddEdge(int u, int v, int w) {
  ver[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt;
}
int rt1, rt2, lson[Maxt], rson[Maxt], tot = 0;
inline void buildin(int &pos, int l, int r) {
  if (l == r) {
    pos = l;
    return;
  }
  pos = ++tot;
  int mid = l + r >> 1;
  buildin(lson[pos], l, mid), buildin(rson[pos], mid + 1, r);
  AddEdge(lson[pos], pos, 0), AddEdge(rson[pos], pos, 0);
}
inline void buildout(int &pos, int l, int r) {
  if (l == r) {
    pos = l;
    return;
  }
  pos = ++tot;
  int mid = l + r >> 1;
  buildout(lson[pos], l, mid), buildout(rson[pos], mid + 1, r);
  AddEdge(pos, lson[pos], 0), AddEdge(pos, rson[pos], 0);
}
inline void modify(int pos, int l, int r, int L, int R, int u, int w, int typ) {
  if (L <= l && R >= r)
    return typ == 2 ? AddEdge(u, pos, w) : AddEdge(pos, u, w);
  int mid = l + r >> 1;
  if (L <= mid) modify(lson[pos], l, mid, L, R, u, w, typ);
  if (R > mid) modify(rson[pos], mid + 1, r, L, R, u, w, typ);
}
struct state {
  int u;
  long long d;
  state(void) { u = d = 0; }
  state(int _u, long long _d) : u(_u), d(_d) {}
  inline bool operator<(const state &rhs) const { return d > rhs.d; }
};
long long dis[Maxt];
bool vis[Maxt];
inline void Dijkstra(void) {
  priority_queue<state> q;
  memset(dis, 0x3f, sizeof(dis));
  dis[s] = 0;
  q.push(state(s, dis[s]));
  while (!q.empty()) {
    int u = q.top().u;
    q.pop();
    if (vis[u]) continue;
    vis[u] = true;
    for (int i = head[u]; i; i = nxt[i]) {
      if (dis[ver[i]] > dis[u] + edge[i]) {
        dis[ver[i]] = dis[u] + edge[i];
        q.push(state(ver[i], dis[ver[i]]));
      }
    }
  }
  for (int i = 1; i <= n; i++)
    writeln(dis[i] == 0x3f3f3f3f3f3f3f3f ? -1 : dis[i], i == n ? '\n' : ' ');
}
signed main(void) {
  read(n), read(q), read(s);
  tot = n;
  buildin(rt1, 1, n), buildout(rt2, 1, n);
  for (int i = 1, opt, v, l, r, w; i <= q; i++) {
    read(opt);
    if (opt == 1) {
      read(l), read(r), read(w);
      AddEdge(l, r, w);
    } else if (opt == 2) {
      read(v), read(l), read(r), read(w);
      modify(rt2, 1, n, l, r, v, w, 2);
    } else {
      read(v), read(l), read(r), read(w);
      modify(rt1, 1, n, l, r, v, w, 3);
    }
  }
  Dijkstra();
  return 0;
}
