#include<bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
const int N=2e6+10;
const int mod=1e9+7;
const int null=2147483647;
#define endl '\n'
typedef long long ll;
ll ans=0,n1,m1;
ll t=0,s1=0,s2=0,s3=0,max1=0,max2=0,w,min1=100000000,sum=0,n,m,i,j,k=0,v,sie,cnt,x,y,z,s;
int first[N],d[N],vis[N],spend[N];
/*inline int read() {
bool sym=0;
int res=0;
char ch=getchar();
while(!isdigit(ch))sym |=(ch =='-'),ch=getchar();
while(isdigit(ch)) res =(res<<3)+(res<<1)+(ch^48),ch=getchar();
return sym ? -res : res;
}
void print(int x) {
if(!x)return;
print(x/10);
putchar(x%10+'0');
}*/
priority_queue<pair<ll,ll> ,vector<pair<ll,ll> > ,greater<pair<ll,ll> > >q;// 堆优化
struct edge {
ll to,next,w,co;
}edges[N];
void add(ll u,ll v,ll w,ll co)// 链式前向星存图
{
edges[++cnt].to =v;
edges[cnt].w =w;
edges[cnt].co =co;
edges[cnt].next =first[u];
first[u]=cnt;
}
void dijkstra(int st){
for(i=0;i<n;i++){
d[i]=2147483647;
}
d[st]=0;spend[st]=0;//初始化 spend 和 dis
q.push({d[st],st});
while(q.size()){
ll u=q.top().second;q.pop();
if(vis[u])continue;
vis[u]=1;
for(i=first[u];i;i=edges[i].next){
ll v=edges[i].to ;
if(d[v]>d[u]+edges[i].w ){
d[v]=d[u]+edges[i].w ;
spend[v]=spend[u]+edges[i].co;
q.push({d[v],v});
}
else
if(d[v]==d[u]+edges[i].w )//路径最短时,寻找每个点最大或最小费用
{
if(spend[v]>spend[u]+edges[i].co)
spend[v]=spend[u]+edges[i].co,q.push({d[v],v});
}
}
}
}
int main()
{
cin>>n>>m>>n1>>m1;
for(i=0;i<m;i++){
cin>>x>>y>>z>>s1;
add(x,y,z,s1);
add(y,x,z,s1);//无向图
}
dijkstra(n1);
cout<<d[m1]<<endl;
cout<<spend[m1];
return 0;
}
//mio lover
还是很基础的,算个模板