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 C (GCC 5.4.1) (judge verdict: Accepted)

#include<stdio.h>
#include<stdlib.h>
#define INF 1000000000000001
#define NMAX 100000
#define MIN(a, b) ((a) < (b) ? (a) : (b))
struct node {
  int id;
  int weight[2];
  struct node *next;
};
struct node *list[NMAX];
int heap[NMAX], heap_index[NMAX], heapsize;
long long int dist[2][NMAX];
void Insert(int, int, int, int);
void downheap(int, int);
void upheap(int, int);
void PQ_Init(int, int);
void DijkstraPQ(int, int, int);
int main(void)
{
  int i, j, n, m, s, t, u, v, a, b;
  long long int ans[NMAX];
  scanf("%d %d %d %d", &n, &m, &s, &t);
  for (i = 0; i < n; i++) list[i] = NULL;
  for (i = 0; i < m; i++) {
    scanf("%d %d %d %d", &u, &v, &a, &b);
    Insert(u - 1, v - 1, a, b);
  }
  DijkstraPQ(s - 1, t - 1, n);
  ans[n-1] = dist[0][n-1] + dist[1][n-1];
  for (i = n - 2; i >= 0; i--) ans[i] = MIN(ans[i+1], dist[0][i] + dist[1][i]);
  for (i = 0; i < n; i++) {
    struct node *p, *q;
    printf("%lld\n", INF - ans[i] - 1);
    if (list[i] != NULL) {
      for (q = list[i], p = q->next; p != NULL; q = p, p = p->next) {
        q->next = p->next;
        free(p);
      }
      free(list[i]);
    }
  }
}
void Insert(int a, int b, int weight1, int weight2)
{
  struct node *p = (struct node*)malloc(sizeof(struct node));
  p->id = b;
  p->weight[0] = weight1;
  p->weight[1] = weight2;
  p->next = list[a];
  list[a] = p;
  p = (struct node*)malloc(sizeof(struct node));
  p->id = a;
  p->weight[0] = weight1;
  p->weight[1] = weight2;
  p->next = list[b];
  list[b] = p;
}
void downheap(int k, int index)
{
  int j, v = heap[k];
  while (k < heapsize / 2) {
    j = 2 * k + 1;
    if (j < heapsize - 1 && dist[index][heap[j]] > dist[index][heap[j + 1]]) j++;
    if (dist[index][v] <= dist[index][heap[j]]) break;
    heap[k] = heap[j];
    heap_index[heap[j]] = k;
    k = j;
  }
  heap[k] = v;
  heap_index[v] = k;
}
void upheap(int j, int index)
{
  int k, v = heap[j];
  while (j > 0) {
    k = (j + 1) / 2 - 1;
    if (dist[index][v] >= dist[index][heap[k]]) break;
    heap[j] = heap[k];
    heap_index[heap[k]] = j;
    j = k;
  }
  heap[j] = v;
  heap_index[v] = j;
}
void PQ_Init(int size, int index)
{
  int i;
  heapsize = size;
  for (i = 0; i < size; i++) {
    heap[i] = i;
    heap_index[i] = i;
  }
  for (i = size / 2 - 1; i >= 0; i--) downheap(i, index);
}
void DijkstraPQ(int p, int q, int size)
{
  int i;
  for (i = 0; i < size; i++) dist[0][i] = INF;
  dist[0][p] = 0;
  PQ_Init(size, 0);
  while (heapsize > 0) {
    struct node *n;
    int u = heap[0];
    heap[0] = heap[heapsize - 1];
    heap_index[heap[heapsize - 1]] = 0;
    heapsize--;
    downheap(0, 0);
    for (n = list[u]; n != NULL; n = n->next) {
      int w = n->weight[0];
      long long int newlen = dist[0][u] + w;
      if (newlen < dist[0][n->id]) {
        dist[0][n->id] = newlen;
        upheap(heap_index[n->id], 0);
      }
    }
  }
  for (i = 0; i < size; i++) dist[1][i] = INF;
  dist[1][q] = 0;
  PQ_Init(size, 1);
  while (heapsize > 0) {
    struct node *n;
    int u = heap[0];
    heap[0] = heap[heapsize - 1];
    heap_index[heap[heapsize - 1]] = 0;
    heapsize--;
    downheap(0, 1);
    for (n = list[u]; n != NULL; n = n->next) {
      int w = n->weight[1];
      long long int newlen = dist[1][u] + w;
      if (newlen < dist[1][n->id]) {
        dist[1][n->id] = newlen;
        upheap(heap_index[n->id], 1);
      }
    }
  }
}