#include <stdio.h>
#include <vector>
#define MAX 10000000
using namespace std; //使用vector要加这句
struct E
{
int next;
int d;
int cost;
};
vector<E> edge[1001];
int dist[1001];
int cost[1001];
bool mark[1001];
int main()
{
int n, m;
int S, T;
while(scanf("%d%d", &n, &m) != EOF && n != 0)
{
for(int i = 1; i <= n; i++)
edge[i].clear();
//输入
int a, b, c, d;
for(int i = 0; i < m; i++)
{
scanf("%d%d%d%d", &a, &b, &c, &d);
E temp;
temp.cost = d;
temp.d = c;
temp.next = a;
edge[b].push_back(temp);
temp.next = b;
edge[a].push_back(temp);
}
//初始化
for(int i = 1; i <= n; i++)
{
dist[i] = -1;
cost[i] = MAX; //要注意把cost也初始化
mark[i] = false;
}
scanf("%d%d", &S, &T);
dist[S] = 0;
cost[S] = 0;
mark[S] = true;
int u = S;
for(int k = 1; k < n; k++)
{
for(int j = 0; j < edge[u].size(); j++)
{
int t = edge[u][j].next;
int d = edge[u][j].d;
int c = edge[u][j].cost;
if(mark[t] == true)
continue;
//在有多条路径时把cost的判断条件加到这里
if(dist[t] == -1 || dist[t] > dist[u] + d || (dist[t] == dist[u] + d && cost[t] > cost[u] + c))
{
dist[t] = dist[u] + d;
cost[t] = cost[u] + c;
}
}
int min = MAX;
for(int i = 1; i <= n; i++)
{
if(mark[i] == true)
continue;
if(dist[i] == -1)
continue;
if(min > dist[i])
{
min = dist[i];
u = i;
}
}
mark[u] = true;
}
printf("%d %d\n", dist[T], cost[T]);
}
return 0;
}