Problem:
Score : 400 points

Problem Statement

Kenkoooo is planning a trip in Republic of Snuke.
In this country, there are n cities and m trains running.
The cities are numbered 1 through n, and the i-th train connects City u_i and v_i bidirectionally.
Any city can be reached from any city by changing trains.

Two currencies are used in the country: yen and snuuk.
Any train fare can be paid by both yen and snuuk.
The fare of the i-th train is a_i yen if paid in yen, and b_i snuuk if paid in snuuk.

In a city with a money exchange office, you can change 1 yen into 1 snuuk.
However, when you do a money exchange, you have to change all your yen into snuuk.
That is, if Kenkoooo does a money exchange when he has X yen, he will then have X snuuk.
Currently, there is a money exchange office in every city, but the office in City i will shut down in i years and can never be used in and after that year.

Kenkoooo is planning to depart City s with 10^{15} yen in his pocket and head for City t, and change his yen into snuuk in some city while traveling.
It is acceptable to do the exchange in City s or City t.

Kenkoooo would like to have as much snuuk as possible when he reaches City t by making the optimal choices for the route to travel and the city to do the exchange.
For each i=0,...,n-1, find the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i years.
You can assume that the trip finishes within the year.

Constraints

2 \leq n \leq 10^5

1 \leq m \leq 10^5

1 \leq s,t \leq n

s \neq t

1 \leq u_i < v_i \leq n

1 \leq a_i,b_i \leq 10^9

If i\neq j, then u_i \neq u_j or v_i \neq v_j.

Any city can be reached from any city by changing trains.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

n m s t
u_1 v_1 a_1 b_1
:
u_m v_m a_m b_m

Output

Print n lines.
In the i-th line, print the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i-1 years.

Sample Input 1

4 3 2 3
1 4 1 100
1 2 1 10
1 3 20 1

Sample Output 1

999999999999998
999999999999989
999999999999979
999999999999897

After 0 years, it is optimal to do the exchange in City 1.

After 1 years, it is optimal to do the exchange in City 2.

Note that City 1 can still be visited even after the exchange office is closed.
Also note that, if it was allowed to keep 1 yen when do the exchange in City 2 and change the remaining yen into snuuk, we could reach City 3 with 999999999999998 snuuk, but this is NOT allowed.

After 2 years, it is optimal to do the exchange in City 3.

After 3 years, it is optimal to do the exchange in City 4.
Note that the same train can be used multiple times.

Sample Input 2

8 12 3 8
2 8 685087149 857180777
6 7 298270585 209942236
2 4 346080035 234079976
2 5 131857300 22507157
4 8 30723332 173476334
2 6 480845267 448565596
1 4 181424400 548830121
4 5 57429995 195056405
7 8 160277628 479932440
1 6 475692952 203530153
3 5 336869679 160714712
2 7 389775999 199123879

Sample Output 2

999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994

Solution in Fortran (gfortran v4.8.4) (judge verdict: Wrong Answer)

module module_sort
    implicit none
    interface sort
        module procedure int_heap_sort, real_heap_sort
    end interface

    contains

        subroutine int_heap_down(a,node,las)
            implicit none
            integer(8) a(*),x
            integer(8) node,par,ch1,ch2,las
            par = node
            x = a(par); ch1 = par*2
            do while(ch1 <= las)
                ch2 = ch1+1
                if(ch2 <= las .and. a(ch1) < a(ch2)) ch1 = ch2
                if(a(ch1) > x) then
                    a(par) = a(ch1); a(ch1) = x
                else 
                    exit
                endif
                par = ch1; ch1 = par*2
            enddo
        end subroutine int_heap_down

        subroutine int_heap_sort(a,n)
            implicit none
            integer(8) a(*),x
            integer(8) n,i
            do i = n/2, 1, -1
                call int_heap_down(a,i,n)
            enddo
            do i=n,2,-1
                x = a(i); a(i) = a(1); a(1) = x
                call int_heap_down(a,1_8,i-1)
            enddo
        end subroutine int_heap_sort

        subroutine real_heap_down(a,node,las)
            implicit none
            real a(*), x
            integer(8) node,par,ch1,ch2,las
            par = node
            x = a(par); ch1 = par*2
            do while(ch1 <= las)
                ch2 = ch1+1
                if(ch2 <= las .and. a(ch1) < a(ch2)) ch1 = ch2
                if(a(ch1) > x) then
                    a(par) = a(ch1); a(ch1) = x
                else 
                    exit
                endif
                par = ch1; ch1 = par*2
            enddo
        end subroutine real_heap_down

        subroutine real_heap_sort(a,n)
            implicit none
            real a(*),x
            integer(8) n,i
            do i = n/2, 1, -1
                call real_heap_down(a,i,n)
            enddo
            do i=n,2,-1
                x = a(i); a(i) = a(1); a(1) = x
                call real_heap_down(a,1_8,i-1)
            enddo
        end subroutine real_heap_sort

end module module_sort

module module_deque
    implicit none
    type deque_node
        type(deque_node) ,pointer:: prev => null(),next => null()
        integer(8) val
    end type deque_node

    type deque
        type(deque_node) ,pointer:: first => null(),last => null()
        integer(8):: size=0
        contains
            procedure:: push_back => deque_push_back
            procedure:: push_front => deque_push_front
            procedure:: pop_back => deque_pop_back
            procedure:: pop_front => deque_pop_front
    end type deque

    contains

        subroutine deque_push_back(self,val)
            class(deque)::self
            integer(8)::val
            if(self%size == 0) then
                allocate(self%first)
                self%last => self%first
                self%first%val = val
                self%size = 1
            else
                allocate(self%last%next)
                self%last%next%prev => self%last
                self%last => self%last%next
                self%last%val = val
                self%size = self%size+1
            endif
        end subroutine deque_push_back

        subroutine deque_push_front(self,val)
            class(deque)::self
            integer(8)::val
            if(self%size == 0) then
                allocate(self%first)
                self%last => self%first
                self%first%val = val
                self%size = 1
            else
                allocate(self%first%prev)
                self%first%prev%next => self%first
                self%first => self%first%prev
                self%first%val = val
                self%size = self%size+1
            endif
        end subroutine deque_push_front

        subroutine deque_pop_back(self)
            class(deque)::self
            if(self%size == 0) then
                return
            else if(self%size == 1) then
                self%size = 0
                deallocate(self%last)
                self%last => null(); self%first => null()
            else
                self%last => self%last%prev
                deallocate(self%last%next)
                self%last%next => null()
                self%size = self%size-1
            endif
        end subroutine deque_pop_back

        subroutine deque_pop_front(self)
            class(deque)::self
            if(self%size == 0) then
                return
            else if(self%size == 1) then
                self%size = 0
                deallocate(self%first)
                self%last => null(); self%first => null()
            else
                self%first => self%first%next
                deallocate(self%first%prev)
                self%first%prev => null()
                self%size = self%size-1
            endif
        end subroutine deque_pop_front

end module module_deque

module module_RedBlackTree
    implicit none
    integer(8),parameter :: red = 1,black = 0
    type RBT_KEY
        character(11) :: k
    end type RBT_KEY
    type RBT_node
        type(RBT_node),pointer :: par=>null(), left => null(),right => null()
        type(RBT_KEY)      :: key
        integer(8)         :: val=0
        integer(8)         :: color=red
    end type RBT_node

    type(RBT_node) ,pointer,save:: rbt_nil

    type RedBlackTree
        type(RBT_node),pointer :: root => null()
        integer(8)         :: size = 0
        contains
            procedure:: insert  => RedBlackTree_Insert
            procedure:: get_val => RedBlackTree_Get
            procedure:: find    => RedBlackTree_Find
            procedure:: add     => RedBlackTree_Add
            procedure:: FixUp   => RedBlackTree_FixUp
            end type RedBlackTree

    contains

        subroutine RedBlackTree_Init()
            implicit none

            if(.not.associated(rbt_nil)) then
                allocate(rbt_nil)
                rbt_nil%color = black
            endif
        
        end subroutine  RedBlackTree_Init

        recursive function RedBlackTree_Get(self,key) result(val)
            implicit none
            class(RedBlackTree), intent(in) :: self
            type(RBT_KEY)                   :: key
            integer(8)                      :: val
            type(RBT_node),pointer              :: u

            u   => SearchTree(self%root,key)
            val = u%val
            return

        end function RedBlackTree_Get

        recursive function RedBlackTree_Find(self,key) result(res)
            implicit none
            class(RedBlackTree), intent(in) :: self
            type(RBT_KEY)                   :: key
            logical                         :: res
            type(RBT_node),pointer              :: u


            u   => SearchTree(self%root,key)
            res = (.not.associated(u,rbt_nil))
            return

        end function RedBlackTree_Find

        recursive subroutine RedBlackTree_Add(self,key,val)
            implicit none
            class(RedBlackTree), intent(inout) :: self
            type(RBT_KEY)                      :: key
            type(RBT_node),pointer                 :: u
            integer(8)                         :: val

            if(.not.associated(self%root)) then
                call self%insert(key,val)
                return
            endif

            u   => SearchTree(self%root,key)
            if (associated(u,rbt_nil)) then
                call self%insert(key,val)
            else
                u%val = u%val+val 
            end if
            return

        end subroutine RedBlackTree_Add

        recursive function SearchTree(u,key) result(res)
            implicit none
            type(RBT_node), pointer  :: u,res
            type(RBT_KEY)        :: key

            if(associated(u,rbt_nil)) then
                res => rbt_nil
                return
            endif

            if(key%k < u%key%k) then
                res => SearchTree(u%left,key)
                return
            else if(key%k > u%key%k) then
                res => SearchTree(u%right,key)
                return
            else
                res => u
                return
            endif

        end function SearchTree

        subroutine RedBlackTree_Insert(self,key,val)
            implicit none
            class(RedBlackTree),intent(inout):: self
            type(RBT_KEY),intent(in)         :: key
            integer(8),intent(in)            :: val
            type(RBT_node),pointer,save          :: now, u

            !allocate new RBT_node
            allocate(u)
            u%key = key; u%val = val
            u%left => rbt_nil; u%right => rbt_nil

            !insert new RBT_node
            if(.not. associated(self%root)) then
                u%left => rbt_nil; u%right => rbt_nil; u%par => rbt_nil
                self%root => u
                self%root%color = black
                self%size = 1
                return
            else
                now => self%root
                if(.not.Insert_RBT_node(u,now)) return
            endif

            !Fix Tree
            call self%FixUp(u)

            self%size = self%size+1
            
        end subroutine RedBlackTree_Insert

        recursive function Insert_RBT_node(u,now) result(added) 
            implicit none
            type(RBT_node), pointer:: u,now
            logical            :: added
            
            if(u%key%k < now%key%k) then
                if(associated(now%left,rbt_nil)) then
                    now%left => u
                    u%par => now
                    added = .true.
                else
                    now => now%left
                    added = Insert_RBT_node(u,now)
                endif
                return
            else if(u%key%k > now%key%k) then
                if(associated(now%right,rbt_nil)) then
                    now%right => u
                    u%par => now
                    added = .true.
                else
                    now => now%right
                    added = Insert_RBT_node(u,now)
                endif
                return
            else
                added = .false.
                return
            endif

        end function Insert_RBT_node 

        subroutine RedBlackTree_FixUp(self,u)
            implicit none
            class(RedBlackTree),intent(inout) :: self
            type(RBT_node),pointer,intent(inout)  :: u
            type(RBT_node),pointer                :: w,g

            nullify(w,g)
            do while(u%color == red)
                if(u%key%k == self%root%key%k) then
                    u%color = black
                    return
                endif
                w => u%par
                if(w%left%color == black) then
                    call FripLeft(w,self%root)
                    u => w
                    w => u%par
                endif
                if(w%color == black) return
                g => w%par
                if(g%right%color == black) then
                    call FripRight(g,self%root)
                    return
                else
                    call PushBlack(g)
                    u => g
                endif
            enddo
        
        end subroutine RedBlackTree_FixUp

        subroutine PushBlack(u)
            implicit none
            type(RBT_node), pointer:: u

            u%color = red; u%left%color = black; u%right%color = black; 

        end subroutine PushBlack

        subroutine PullBlack(u)
            implicit none
            type(RBT_node), pointer:: u

            u%color = black; u%left%color = red; u%right%color = red; 

        end subroutine PullBlack

        subroutine FripLeft(u,root)
            implicit none
            type(RBT_node), pointer, intent(inout) :: root
            type(RBT_node), pointer                :: u,w
            integer(8)                         :: tmp
            
            tmp = u%color; u%color = u%right%color; u%right%color = tmp

            w => u%right
            w%par => u%par
            if(.not.associated(u%par,rbt_nil)) then
                if(associated(w%par%left,u)) then
                     w%par%left=>w
                else 
                    w%par%right=>w
                endif
            endif
            u%right => w%left
            if(.not.associated(u%right,rbt_nil))u%right%par => u
            u%par => w
            w%left => u
            if(associated(u,root)) then
                root => w
                root%par => rbt_nil
            endif

        end subroutine FripLeft

        subroutine FripRight(u,root)
            implicit none
            type(RBT_node), pointer,intent(inout):: root
            type(RBT_node), pointer              :: u,w
            integer(8)                       :: tmp

            tmp = u%color; u%color = u%left%color; u%left%color = tmp

            w => u%left
            w%par => u%par
            if(.not.associated(u%par,rbt_nil)) then
                if(associated(w%par%left,u)) then
                    w%par%left=>w
                else 
                    w%par%right=>w
                endif
            endif
            u%left => w%right
            if(.not.associated(u%left,rbt_nil))u%left%par => u
            u%par => w
            w%right => u
            if(associated(u,root)) then
                root => w
                root%par => rbt_nil
            endif

        end subroutine FripRight

end module module_RedBlackTree

module module_MinHeap
    implicit none
    type HEAP_TYPE
        integer(8) ::key,val
    end type HEAP_TYPE

    type MH_node
        type(MH_node),pointer :: par=>null(), left => null(),right => null()
        type(HEAP_TYPE)    :: cont
        integer(8)         :: size
    end type MH_node
    type(MH_node) ,pointer,save:: heap_nil

    type MinHeap
        type(MH_node),pointer :: root,last
        contains
            procedure:: push => MinHeap_Insert_MH_node
            procedure:: pop  => MinHeap_Pop_MH_node
    end type MinHeap

    contains

        subroutine Swap_HEAP_TYPE(a,b)
            implicit none
            type(HEAP_TYPE),pointer :: a,b,tmp

            tmp%key = a%key
            a%key   = b%key
            b%key   = tmp%key
            tmp%val = a%val
            a%val   = b%val
            b%val   = tmp%val

        end subroutine Swap_HEAP_TYPE

        subroutine MinHeap_Up(root,u)
            implicit none
            type(MH_node),pointer      :: root,u
            type(HEAP_TYPE)         :: tmp

            do while(.not.associated(root,u))
                if(u%cont%key < u%par%cont%key) then
                    tmp%key        = u%cont%key
                    u%cont%key     = u%par%cont%key
                    u%par%cont%key = tmp%key
                    tmp%val        = u%cont%val
                    u%cont%val     = u%par%cont%val
                    u%par%cont%val = tmp%val
                    u => u%par
                else
                    return
                endif
            enddo
            return

        end subroutine MinHeap_Up

        subroutine MinHeap_Down(root)
            implicit none
            type(MH_node),pointer      :: root,u
            type(HEAP_TYPE)         :: tmp

            u => root
            do while(.not.associated(u%left,heap_nil))

                if(.not.associated(u%right,heap_nil)) then
                    if (u%right%cont%key < u%left%cont%key .and. u%right%cont%key < u%cont%key) then
                        tmp%key          = u%cont%key
                        u%cont%key       = u%right%cont%key
                        u%right%cont%key = tmp%key
                        tmp%val          = u%cont%val
                        u%cont%val       = u%right%cont%val
                        u%right%cont%val = tmp%val
                        u => u%right
                        cycle
                    endif
                endif
                if(u%left%cont%key < u%cont%key) then
                    tmp%key         = u%cont%key
                    u%cont%key      = u%left%cont%key
                    u%left%cont%key = tmp%key
                    tmp%val         = u%cont%val
                    u%cont%val      = u%left%cont%val
                    u%left%cont%val = tmp%val
                    u => u%left
                    cycle
                endif
                exit
            enddo
            return

        end subroutine MinHeap_Down

        subroutine Update_Size(root,u,is_add)
            implicit none
            type(MH_node),pointer :: root,u
            logical            :: is_add

            do while(.not.associated(root,u))
                if(is_add) then
                    u%size = u%size+1
                else
                    u%size = u%size-1
                endif
                u => u%par
            enddo

            if(is_add) then
                u%size = u%size+1
            else
                u%size = u%size-1
            endif

        end subroutine Update_size

        subroutine MinHeap_Insert_MH_node(self,cont)
            implicit none
            class(MinHeap)     :: self
            type(MH_node),pointer :: u,now
            type(HEAP_TYPE)    :: cont

            if(.not.associated(heap_nil)) allocate(heap_nil)
            u => null()
            allocate(u)
            u%cont = cont
            u%left => heap_nil; u%right => heap_nil
            u%size = 1

            if(.not.associated(self%root)) then
                self%root      => u
                self%root%par  => heap_nil
                return
            endif

            now => self%root
            do
                now%size = now%size+1
                if(.not.associated(now%left,heap_nil)) then
                    if(.not.associated(now%right,heap_nil)) then
                        if(now%right%size < now%left%size) then
                            now => now%right; cycle
                        else
                            now => now%left;  cycle
                        endif
                    else
                        now%right => u
                        u%par     => now
                        exit
                    endif
                else
                    now%left => u
                    u%par    => now
                    exit
                endif
            enddo

            call MinHeap_Up(self%root,u)

        end subroutine MinHeap_Insert_MH_node

        subroutine MinHeap_Pop_MH_node(self)
            implicit none
            class(MinHeap)     :: self
            type(MH_node),pointer :: u,now
            type(HEAP_TYPE)    :: tmp

            if(.not.associated(heap_nil)) allocate(heap_nil)
            if(.not.associated(self%root)) return

            now => self%root
            do
                now%size = now%size-1
                if(.not.associated(now%left,heap_nil)) then
                    if(.not.associated(now%right,heap_nil)) then
                        if(now%right%size >= now%left%size) then
                            now => now%right; cycle
                        else
                            now => now%left;  cycle
                        endif
                    else
                        u => now%left
                        tmp%key            = u%cont%key
                        u%cont%key         = self%root%cont%key
                        self%root%cont%key = tmp%key
                        tmp%val            = u%cont%val
                        u%cont%val         = self%root%cont%val
                        self%root%cont%val = tmp%val
                        now%left => heap_nil
                        exit
                    endif
                else if(associated(now,self%root)) then
                    deallocate(self%root)
                    return
                else
                    u => now
                    tmp%key            = u%cont%key
                    u%cont%key         = self%root%cont%key
                    self%root%cont%key = tmp%key
                    tmp%val            = u%cont%val
                    u%cont%val         = self%root%cont%val
                    self%root%cont%val = tmp%val
                    if(associated(now%par%left,now)) then
                        now%par%left => heap_nil
                    else
                        now%par%right => heap_nil
                    endif
                    exit
                endif
            enddo

            deallocate(u)

            call MinHeap_Down(self%root)

        end subroutine MinHeap_Pop_MH_node

end module module_MinHeap

module global
    use module_sort
    use module_deque
    use module_RedBlackTree
    use module_MinHeap
    implicit none
    integer(8)  :: n,m,s,t,u,v,a,b,ds(100005),dt(100005),ans(100005),mm
    type(deque) :: to(200005),yen(200005),snk(200005)
    type(deque_node),pointer :: tp,yp,sp
    type(HEAP_TYPE) heap_t
    type(MinHeap) pque
end module global

program main
    use global
    integer(8) i
    integer(8) now,dist,nex

    call RedBlackTree_Init()

    read *,n,m,s,t

    do i=1,m
        read*, u,v,a,b
        call to(u)%push_back(v)
        call yen(u)%push_back(a)
        call snk(u)%push_back(b)
        call to(v)%push_back(u)
        call yen(v)%push_back(a)
        call snk(v)%push_back(b)
    enddo

    do i=1,n+3
        ds(i) = 1e15_8
        dt(i) = 1e15_8
    enddo

    heap_t%key = 0; heap_t%val = s
    call pque%push(heap_t)
    ds(s) = 0
    do while(associated(pque%root))
        now  = pque%root%cont%val
        dist = pque%root%cont%key 
        call pque%pop()
        if(dist > ds(now)) cycle
        tp => to(now)%first
        yp => yen(now)%first
        do
            nex = tp%val
            if(ds(nex) > dist+yp%val) then
                ds(nex) = dist+yp%val
                heap_t%key = dist+yp%val
                heap_t%val = nex
                call pque%push(heap_t)
            endif
            if(associated(tp,to(now)%last)) exit
            tp => tp%next
            yp => yp%next
        enddo
    enddo

    heap_t%key = 0; heap_t%val = t
    call pque%push(heap_t)
    dt(t) = 0
    do while(associated(pque%root))
        now  = pque%root%cont%val
        dist = pque%root%cont%key 
        call pque%pop()
        if(dist > ds(now)) cycle
        tp => to(now)%first
        sp => snk(now)%first
        do
            nex = tp%val
            if(dt(nex) > dist+sp%val) then
                dt(nex) = dist+sp%val
                heap_t%key = dist+sp%val
                heap_t%val = nex
                call pque%push(heap_t)
            endif
            if(associated(tp,to(now)%last)) exit
            tp => tp%next
            sp => sp%next
        enddo
    enddo

    mm = 1e15_8

    do i = n, 1,-1
        if(ds(i) /= 1e15_8 .and. dt(i) /= 1e15_8) mm = min(mm,ds(i)+dt(i))
        ans(i) = 1000000000000000_8-mm
    enddo

    do i = 1,n
        print '(i0)',ans(i)
    enddo

end program main