import java.util.PriorityQueue

data class Edge(val from: Int, val to: Int, val cost: Long)

data class State(val v: Int, val cost: Long)

fun compareState(s1: State, s2: State): Int {
  if (s1.cost > s2.cost) return 1
  if (s1.cost < s2.cost) return -1
  return 0
}

fun shortestPath(graph: Array<MutableList<Edge>>, s: Int): LongArray {
  val n = graph.size
  // Dijkstra from s
  // Kotlin 1.0 workaround.
  val pq = PriorityQueue<State>(11, { s1: State, s2: State -> compareState(s1, s2) })
  val dist = LongArray(n, { Long.MAX_VALUE })
  dist[s] = 0
  pq.add(State(s, 0L))
  while (pq.isNotEmpty()) {
    val state = pq.poll()!!
    if (dist[state.v] < state.cost) continue
    for (e in graph[state.v]) {
      if (state.cost + e.cost < dist[e.to]) {
        dist[e.to] = state.cost + e.cost
        pq.add(State(e.to, state.cost + e.cost))
      }
    }
  }
  return dist
}

fun main(args: Array<String>) {
  val (n, m, sRaw, tRaw) = readLine()!!.split(" ").map { it.toInt() }
  val s = sRaw - 1
  val t = tRaw - 1
  val aGraph = Array(n, { mutableListOf<Edge>() })
  val bGraph = Array(n, { mutableListOf<Edge>() })
  repeat(m) {
    val (uRaw, vRaw, a, b) = readLine()!!.split(" ").map { it.toInt() }
    val u = uRaw - 1
    val v = vRaw - 1
    aGraph[u].add(Edge(u, v, a.toLong()))
    aGraph[v].add(Edge(v, u, a.toLong()))
    bGraph[u].add(Edge(u, v, b.toLong()))
    bGraph[v].add(Edge(v, u, b.toLong()))
  }
  val distArrayA = shortestPath(aGraph, s)
  val distArrayB = shortestPath(bGraph, t)
  val costs = mutableListOf<Long>()
  var currentCost = Long.MAX_VALUE
  for (i in n - 1 downTo 0) {
    currentCost = Math.min(currentCost, distArrayA[i] + distArrayB[i])
    costs.add(currentCost)
  }
  costs.reverse()

  val output = StringBuilder()
  for (cost in costs) {
    output.append(1000000000000000L - cost)
    output.append('\n')
  }
  print(output)
}