#include<iostream>
using namespace std;
#define MAXdist 1<<29  //无穷大,代表无法到达
#define MAX 1001
int graph[MAX][MAX][2];//[][][0]len, [][][1]prize
int path[MAX][MAX];
int n, m;
int dist = 0, cost = 0;
void get_dist_and_cost(int s,int t) {//根据path和graph获得s to t的最短路径与费用
	if (path[s][t] == -1) {
		dist += graph[s][t][0];
		cost += graph[s][t][1];
	}
	else {
		int mid = path[s][t];//中间城市
		get_dist_and_cost(s, mid);
		get_dist_and_cost(mid, t);
	}
}
int main() {
	
	cin >> n >> m;
	for(int i=1;i<=n;i++)
		for (int j = 1; j <= n; j++) {
			graph[i][j][0] = graph[i][j][1] = MAXdist;
			path[i][j] = -1;
		}
	for (int i = 1; i <= m; i++) {
		int a, b, d, p;
		cin >> a >> b >> d >> p;
		if (d<graph[a][b][0] ||(d== graph[a][b][0]&&p< graph[a][b][1])) {
			graph[a][b][0] = d; graph[a][b][1] = p;
			graph[b][a][0] = d; graph[b][a][1] = p;
		}
	}
	int s, t;
	cin >> s >> t;
	//floyed算法
	for (int v = 1; v <= n; v++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				if (i == j || i == v || j == v)continue;
				if (graph[i][j][0] > graph[i][v][0] + graph[v][j][0]) {
					graph[i][j][0] = graph[i][v][0] + graph[v][j][0];
					graph[i][j][1] = graph[i][v][1] + graph[v][j][1];
					path[i][j] = v;
				}
				if (graph[i][j][0] == graph[i][v][0] + graph[v][j][0]&&
					graph[i][j][1] > graph[i][v][1] + graph[v][j][1]) {
					graph[i][j][0] = graph[i][v][0] + graph[v][j][0];
					graph[i][j][1] = graph[i][v][1] + graph[v][j][1];
					path[i][j] = v;
				}	
			}
		}
	}
	get_dist_and_cost(s,t);
	cout << dist << " " << cost << endl;

	return 0;
}