import java.util.Scanner

import scala.collection.mutable.PriorityQueue

object Main extends App {

  val sc = new Scanner(System.in)

  val init = 1e15.toLong

  val (n, m, s, t) = (sc.nextInt, sc.nextInt, sc.nextInt - 1, sc.nextInt - 1)

  val g = (1 to m).map(_ => (sc.nextInt - 1, sc.nextInt - 1, sc.nextLong, sc.nextLong))
    .flatMap {
      case (u, t, a, b) => Seq((u, t, a, b), (t, u, a, b))
    }
    .groupBy(_._1)
    .map {
      case (s, seq) => (s, seq.map { case (_, t, a, b) => (t, a, b) })
    }

  val yenSeq = dijkstra(s, g, { case (_, a, _) => a } ).reverse
  val snkSeq = dijkstra(t, g, { case (_, _, b) => b } ).reverse

  val (_, ans) = yenSeq.zip(snkSeq)
    .foldLeft(0L, Seq.empty[Long]) {
      case ((cur, seq), (yen, snk)) =>
        val ans = math.max(cur, init - yen - snk)
        (ans, Seq(ans) ++ seq)
    }

  ans.foreach(println)

  def dijkstra(s: Int, g: Map[Int, Seq[(Int, Long, Long)]], f:((Int, Long, Long)) => Long): Seq[Long] = {
    val pq = new PriorityQueue[(Int, Long)]()

    val score = Array.fill(n)(1L << 50)
    score(s) = 0
    pq.enqueue((s, 0L))

    while (pq.nonEmpty) {
      val (p, c) = pq.dequeue
      for {
        tup <- g.getOrElse(p, Seq.empty)
        if score(tup._1) > c + f(tup)
      } yield {
        score(tup._1) = c + f(tup)
        pq.enqueue((tup._1, c + f(tup)))
      }
    }
    score.toSeq
  }
}
