#include <bits/stdc++.h>
using namespace std;
const int maxn = 5050, INF = 0x7f7f7f7f;
struct Edge
{
int from, to, cap, flow, cost;
Edge():from(0),to(0),cap(0),flow(0),cost(0){}
Edge(int in1,int in2,int in3,int in4,int in5):from(in1),to(in2),cap(in3),flow(in4),cost(in5){}
};
struct MCMF
{
int s, t, n, m;
int cost, flow;
int inq[maxn], p[maxn], a[maxn], d[maxn];
vector<Edge>edges;
vector<int>G[maxn];
void init(int n) {
this->n = n;
for(int i = 0;i < n;i ++) G[i].clear();
edges.clear();
cost = flow = 0;
}
void addedge(int from, int to, int cap, int cost) {
edges.emplace_back(from, to, cap, 0, cost);
edges.emplace_back(to, from, 0, 0, -cost);
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool spfa(int s, int t) {
for(int i = 0;i < n;i ++) d[i] = INF;
memset(inq, 0, (n + 4) << 2);
p[s] = d[s] = 0;
inq[s] = 1;
queue<int> Q;
Q.push(s);
a[s] = INF;
while(!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = 0;
for(int i = 0;i < G[u].size();i ++) {
Edge& e = edges[G[u][i]];
if(e.cap > e.flow && d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u], e.cap - e.flow);
if(!inq[e.to]) {
inq[e.to] = 1;
Q.push(e.to);
}
}
}
}
if(d[t] == INF) return 0;
flow += a[t];
cost += a[t] * d[t];
int u = t;
while(u != s) {
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
u = edges[p[u]].from;
}
return 1;
}
pair<int,int> maxflow(int s, int t) {
this->s = s;
this->t = t;
while(spfa(s, t));
return make_pair(flow, cost);
}
}D;
int main()
{
int n, m, s, t;
scanf("%d %d %d %d", &n, &m, &s, &t);
D.init(n+1);
while(m --) {
static int u, v, w, f;
scanf("%d %d %d %d", &u, &v, &w, &f);
D.addedge(u, v, w, f);
}
pair<int,int> res = D.maxflow(s,t);
printf("%d %d\n", res.first, res.second);
return 0;
}