#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <tuple>
#include <stack>
#include <bitset>
#include <utility>
#include<iomanip>
// #include <numeric>
using namespace std;



typedef unsigned long ul;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<ll> vint;
typedef vector<vector<ll>> vvint;
typedef vector<string> vstring;
typedef vector<vector<string>> vvstring;
typedef vector<char> vchar;
typedef vector<vector<char>> vvchar;
typedef vector<long double> vdouble;
typedef vector<vector<long double>> vvdouble;
typedef vector<vector<vector<long double>>> vvvdouble;
typedef pair<ll,ll> pint;
typedef vector<pint> vpint;

#define rep(i,n) for(ll i=0;i<n;i++)
#define repf(i,f,n) for(ll i=f;i<n;i++)
#define repr(i,n) for(ll i=n-1;i>=0;i--)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define INT_MAX 2147483647
#define LLONG_MAX 9223372036854775807
#define vmax(vec) *max_element(vec.begin(), vec.end())
#define vmin(vec) *min_element(vec.begin(), vec.end())
#define vsort(vec) sort(vec.begin(), vec.end())
#define vsortgr(vec) sort(vec.begin(), vec.end(), greater<ll>())
#define DIVIDER 1000000007


//
// struct Node{
//   vint children;
//   ll index;
//   ll prop;
// };
// struct edge{ll to; ll cost;};



int dy[]={0, 0, 1, -1};
int dx[]={1, -1, 0, 0,};

// ll X,Y,Z,K;
// ll pmax = 30000000000;
// vint A,B,C;




// int binary_search(int key){
//  //isOKを満たす要素のうち最小のインデックスを返す。（要ソート）
//   int left = -1;
//   int right = N;
//
//   while(right - left > 1){
//     int mid = left + (right - left)/2;
//
//     if(isOK(mid, key)) right=mid;
//     else left=mid;
//   }
//
//   return right;
// }

// ll gcd(ll m, ll n){
//   if(m<n) swap(m,n);
//   if(n==0) return m;
//   return gcd(n, m%n);
// }

// ll get_pow(ll x, ll y){
//   ll ret=0;
//   ll temp = y;
//   while(true){
//     if(x<=temp) break;
//     ret++;
//     temp *= 2;
//   }
//   return ret;
// }

void dikstra(ll n, ll s, vint &dp, vector<vpint> &edge){
  bool used[n];
  rep(i,n)used[i]=false;
  // ll cnt = 0;
  dp = vint(n, LLONG_MAX);
  priority_queue<pint> pq;
  pq.push(mp(0, s));
  while(!pq.empty()){
    ll dist, id;
    tie(dist, id) = pq.top();
    pq.pop();
    // if(dp[id] < -1*dist) continue;
    if(used[id]) continue;
    // cnt++;
    used[id]=true;
    dp[id] = -1*dist;
    for(pint e:edge[id]){
      if(dp[e.fi] < -1*dist+e.se) continue;
      pq.push(mp(dist-e.se, e.fi));
    }
  }

}




int main() {
  cout<<fixed<<setprecision(10);

  ll n,m,s,t;
  cin>>n>>m>>s>>t;
  s--;t--;

  vint u(m),v(m),a(m),b(m);
  vector<vpint> edgey(n);
  vector<vpint> edges(n);

  rep(i,m){
    cin>>u[i]>>v[i]>>a[i]>>b[i]; u[i]--;v[i]--;
    edgey[u[i]].pb(mp(v[i], a[i]));
    edgey[v[i]].pb(mp(u[i], a[i]));
    edges[u[i]].pb(mp(v[i], b[i]));
    edges[v[i]].pb(mp(u[i], b[i]));
  }



  vint dpy, dps;
  dikstra(n,s,dpy,edgey);
  dikstra(n,t,dps,edges);

  vint total(n);
  rep(i,n){
    total[i] = dpy[i]+dps[i];
  }

  for(ll i = n-2;i>=0;i--){
    total[i] = min(total[i], total[i+1]);
  }

  ll maxval = 1e15;
  rep(i,n)cout<<maxval-total[i]<<endl;




}

















//


Measured memory_bytes: 22200