#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4+10;
const int maxm = 1e5+10;
const int INF = 0x3f3f3f3f;
int s, t, n, m;
struct Edge{
int v, cost, cap, next, flow;
}edge[maxm];
int head[maxn];
int pre[maxn];
int tot;
int dis[maxn];
bool vis[maxn];
void init(){
memset(pre, -1, sizeof(pre));
memset(head, -1, sizeof(head));
tot = 0;
}
void add_edge(int u, int v, int weight, int price){
edge[tot].v = v;
edge[tot].cost = price;
edge[tot].cap = weight;
edge[tot].flow = 0;
edge[tot].next = head[u];
head[u] = tot++;
edge[tot].v = u;
edge[tot].cost = -1*price;
edge[tot].cap = 0;
edge[tot].flow = 0;
edge[tot].next = head[v];
head[v] = tot++;
}
bool SPFA(int s, int t){
for(int i=0; i<maxn; i++) dis[i] = INF;
dis[s] = 0;
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
queue<int> q;
while(!q.empty()) q.pop();
q.push(s);
vis[s] = true;
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i=head[u]; ~i; i=edge[i].next){
int v = edge[i].v;
if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost){
dis[v] = dis[u]+edge[i].cost;
pre[v] = i;
if(!vis[v]){
q.push(v);
vis[v] = true;
}
}
}
}
if(pre[t] == -1) return false;
return true;
}
int min_cost_max_flow(int s, int t, int &min_cost){
int flow = 0;
while(SPFA(s, t)){
int Min = INF;
for(int i = pre[t]; ~i; i = pre[edge[i^1].v]){
if(Min>edge[i].cap-edge[i].flow){
Min = edge[i].cap - edge[i].flow;
}
}
for(int i=pre[t]; ~i; i = pre[edge[i^1].v]){
edge[i].flow += Min;
edge[i^1].flow -= Min;
min_cost += edge[i].cost*Min;
}
flow += Min;
}
return flow;
}
int main(){
while(cin>>n>>m>>s>>t){
init();
int u, v, price, weight;
for(int i=0; i<m; i++){
cin>>u>>v>>price>>weight;
add_edge(u, v, weight, price);
}
int min_cost = 0;
int ans = min_cost_max_flow(s, t, min_cost);
cout<<min_cost<<" "<<ans<<endl;
}
return 0;
}