#include<stdio.h>
#include<vector>
using namespace std;
struct E{ //此题中使用vector构成一个二维数组
int next;
int c, p;
};
vector<E>edge[101]; //邻接链表
bool mark[101]; //是否在标记数组(开始的点集)内
int Dis[101]; //距离数组
int cos[101]; //花费数组
int main(){
int n, m, i, j, x, y, z, p;
while(~scanf("%d%d", &n, &m)){
for(i = 1;i <= n; i++) edge[i].clear();
for(i = 0; i < m; i++){
scanf("%d%d%d%d",&x,&y,&z,&p);
E tmp;
tmp.next = y;
tmp.c = z;
tmp.p = p;
edge[x].push_back(tmp); //edge[x].push_back()函数
tmp.next = x;
edge[y].push_back(tmp);
}
int st=0,en = 0;
scanf("%d%d", &st, &en);
for(i = 1; i <= n; i++){
Dis[i] = -1;
mark[i] = false;
}
mark[st] = true; //把起点放入标记数组
Dis[st] = 0; //置起点到起点的距离为0
int newP = st;
int point, mins = 123123123;
for(i = 1; i < n; i++){ //循环的范围为n-1,因为此前已经加入了一个点
for(j = 0; j < edge[i].size(); j++){ //取每条边的相邻边的个数作为最大值
int e = edge[newP][j].next;
int c = edge[newP][j].c;
int p = edge[newP][j].p;
if(mark[e]) continue; //如果已经加入标记数组,则ass
if((Dis[e]==-1)||(Dis[e]>Dis[newP]+c)||((Dis[e]==Dis[newP]+c)&&(cos[e]>cos[newP]+p))){
Dis[e] = Dis[newP] + c;
cos[e] = cos[newP] + p;
if(Dis[e]<mins){ //记录此次循环的距离最小值,作为下一个加入标记数组的点
mins = Dis[e];
point = e;
}
}
}
newP = point;
mark[point] = true; //循环所得最小值的点加入标记数组
}
printf("%d %d\n", Dis[en], cos[en]);
}
}