#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <bitset>     //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <iomanip>        //do setprecision
#include <ctime>
#include <complex>
using namespace std;

#define FOR(i,b,e) for(int i=(b);i<(e);++i)
#define FORQ(i,b,e) for(int i=(b);i<=(e);++i)
#define FORD(i,b,e) for(int i=(b)-1;i>=(e);--i)
#define REP(x, n) for(int x = 0; x < (n); ++x)

#define ST first
#define ND second
#define PB push_back
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double

const double pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;
const int mod=1000000007;
const int SZ=101010;

//最短路数計算つきDijkstra

struct edge
{
  int to, cost;
  edge(int t,int c){
		to=t;
		cost=c;
	}
	edge(){}
};

LL add(LL a,LL b){
  return (a+b)%mod;
}

typedef vector< vector < edge > > Graph;//隣接リスト

int min_path[SZ]={};//sからの最短経路
int min_path2[SZ]={};//sからの最短経路

template< typename T = LL >
vector< T > Dijkstra(Graph &g, int s,int type)//始点sから各点までの最短距離を保持したvectorを返す
{
  typedef pair< T, int > Pi;//cost,from
  vector< T > min_cost(g.size(), numeric_limits< T >::max());
  priority_queue< Pi, vector< Pi >, greater< Pi > > que;//Pi:cost,from
  que.emplace(0, s);
  min_cost[s] = 0LL;
  if(type==1)min_path[s]=-1;
	else min_path2[s]=-1;
  while(!que.empty()) {
    Pi p = que.top();
    que.pop();
    if(p.first > min_cost[p.second]) continue;
    for(auto &e : g[p.second]) {
      if(p.first + e.cost > min_cost[e.to]) continue;
			if(p.first + e.cost == min_cost[e.to]){
        //min_path[e.to]=add(min_path[p.second],min_path[e.to]);//最短距離が同じだったら経路数は和
				//min_path[e.to]=min_path[p.second]+min_path[e.to];//modなし
			}else {
				//min_path[e.to]=min_path[p.second];//最短距離更新->最短経路更新
        min_cost[e.to] = p.first + e.cost;
        que.emplace(min_cost[e.to], e.to);
			}
			if(type==2)min_path[e.to]=p.ND;
			else min_path2[e.to]=p.ND;
    }
  }
  return (min_cost);
}

int main(){
	LL n,m,s,t,money=1e15;
	LL u[SZ]={},v[SZ]={},a[SZ]={},b[SZ]={};
	cin>>n>>m>>s>>t;
	s--;t--;
	vector< vector<edge> > g;
	vector< vector<edge> > g2;

	g.resize(SZ);
	g2.resize(SZ);

	FOR(i,0,m){cin>>u[i]>>v[i]>>a[i]>>b[i];u[i]--;v[i]--;g[u[i]].emplace_back(v[i],a[i]);g[v[i]].emplace_back(u[i],a[i]);}
	FOR(i,0,m){g2[u[i]].emplace_back(v[i],b[i]);g2[v[i]].emplace_back(u[i],b[i]);}

	//cout<<"test0"<<endl;

	vector<LL> dijk=Dijkstra(g,s,1);
	vector<LL> dijk2=Dijkstra(g2,t,2);
	int ryogae[SZ]={};
	//cout<<"test"<<endl;

	priority_queue<pair<LL,int>> pq;
	FOR(i,0,n){//ryogae
		//cerr<<i<<" "<<dijk[i]<<" "<<dijk2[i]<<endl;
		pq.push(MP(-(dijk[i]+dijk2[i]),i));
	}
	int idx=-1;
	//cout<<"test"<<endl;
	while(!pq.empty()){
		pair<LL,int> pr=pq.top();
		pq.pop();
		if(pr.ND>idx){
			FOR(j,idx+1,pr.ND+1){
				//cerr<<j<<" :"<<pr.ND<<" ";
				ryogae[j]=pr.ND;
			}
			idx=pr.ND;
		}
	}
	FOR(i,0,n){
		//cerr<<i<<" "<<ryogae[i]<<endl;
		cout<<money-(dijk[ryogae[i]]+dijk2[ryogae[i]])<<endl;
	}





    return 0;
}


Measured memory_bytes: 21500