// Original C++ solution (slower):
#include<bits/stdc++.h> //Ithea Myse Valgulious

namespace chtholly{

typedef long long ll;

#define re0 register int

#define rec register char

#define rel register ll

#define gc getchar

#define pc putchar

#define p32 pc(' ')

#define pl puts("")

/*By Citrus*/

inline int read(){

  int x=0,f=1;char c=gc();

  for (;!isdigit(c);c=gc()) f^=c=='-';

  for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');

  return f?x:-x;

  }

template <typename mitsuha>

inline bool read(mitsuha &x){

  x=0;int f=1;char c=gc();

  for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';

  if (!~c) return 0;

  for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');

  return x=f?x:-x,1;

  }

template <typename mitsuha>

inline int write(mitsuha x){

  if (!x) return 0&pc(48);

  if (x<0) x=-x,pc('-');

  int bit[20],i,p=0;

  for (;x;x/=10) bit[++p]=x%10;

  for (i=p;i;--i) pc(bit[i]+48);

  return 0;

  }

inline char fuhao(){

  char c=gc();

  for (;isspace(c);c=gc());

  return c;

  }

}using namespace chtholly;

using namespace std;

#define yi first

#define er second

typedef pair<ll,ll> pll;

typedef vector<ll> vlt;

const ll inf=1e18;

const int yuzu=1e5;

int n=read(),m=read(),s=read(),t=read();

 

struct edge{int to;ll cost;};

vector<edge> lj[2][yuzu|10];

 

vlt pao(int s,int id){

priority_queue<pll,vector<pll>,greater<pll> > q;

vlt d(n+2,inf);

d[s]=0,q.push(pll(0,s));

for (;!q.empty();){

  pll p=q.top();q.pop();

  int v=p.er;

  if (d[v]>=p.yi){

    for (edge e:lj[id][v]){

      if (d[e.to]>d[v]+e.cost){

        d[e.to]=d[v]+e.cost;

        q.push(pll(d[e.to],e.to));

	    } 

	  }

    }

  }return d;

}

 

int main(){

int i;

for (i=1;i<=m;++i){

  int u=read(),v=read();ll a=read(),b=read();

  lj[0][u].push_back(edge{v,a});

  lj[0][v].push_back(edge{u,a});

  lj[1][u].push_back(edge{v,b});

  lj[1][v].push_back(edge{u,b});

  }

vlt gmy=pao(s,0),xhk=pao(t,1),ans(n+2,inf);

for (i=n;i;--i) ans[i]=min(gmy[i]+xhk[i],ans[i+1]);

ll llx=1e15;

for (i=1;i<=n;++i) write(llx-ans[i]),pl;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

const int N=1e5+8;

int n,m,s,t;

long long ans[N];

struct node{

    int cnt,head[N];

    long long cost[N];

    bool flag[N];

    struct Edge {int next, to; long long cost;} edge[N*2];

	queue<int> q;

	void add(int from,int to,long long cost)

	{

		edge[++cnt].next=head[from];

		edge[cnt].to=to;

		edge[cnt].cost=cost;

		head[from]=cnt;

	}

	void spfa(int s)

	{

		for(int i=1;i<=n;i++) cost[i]=1000000000000000000;

		memset(flag,0,sizeof(flag));

		q.push(s); flag[s]=1; cost[s]=0;

		while(!q.empty())

		{

			int x=q.front();

			q.pop();

			flag[x]=0;

			for(int i=head[x];i;i=edge[i].next)

			{

				int to=edge[i].to;

				if(cost[to]>cost[x]+edge[i].cost)

				{

					cost[to]=cost[x]+edge[i].cost;

					if(!flag[to]) q.push(to),flag[to]=1;

				}

			}

		}

	}

}s_to_i,i_to_t;

long long Min(long long x,long long y)

{

    if(x>y) return y;

    return x;

}

int main()

{

    cin>>n>>m>>s>>t;

    for(int i=1;i<=m;i++)

    {

        int u,v;

        long long yen,snu;

        cin>>u>>v>>yen>>snu;

        s_to_i.add(u,v,yen);

        i_to_t.add(u,v,snu);

        s_to_i.add(v,u,yen);

        i_to_t.add(v,u,snu);

    }

    s_to_i.spfa(s);

    i_to_t.spfa(t);

    ans[n]=s_to_i.cost[n]+i_to_t.cost[n];

    for(int i=n-1;i>0;i--) ans[i]=Min(ans[i+1],s_to_i.cost[i]+i_to_t.cost[i]);

    for(int i=1;i<=n;i++) printf("%lld\n",1000000000000000-ans[i]);

}


// Fastest known solution for this problem: