#include <bits/stdc++.h>
#define maxn 200010
#define int long long
using namespace std;
const int inf = INT_MAX;
int n, m, s, t;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
struct EDGE {
int to, nxt, val, w;
} e[maxn << 1];
int head[maxn << 1];
int cnt = 1;
void add(int a, int b, int c, int d) {
e[++cnt].to = b;
e[cnt].val = c;
e[cnt].w = d;
e[cnt].nxt = head[a];
head[a] = cnt;
}
bool vis[maxn];
struct NODE {
int from;
int edge;
} node[maxn];
int dis[maxn];
bool bfs() {
memset(vis, false, sizeof vis);
memset(node, 0, sizeof node);
memset(dis, 0x3f, sizeof dis);
queue<int> q;
q.push(s);
vis[s] = true;
dis[s] = 0;
while (!q.empty()) {
int u = q.front();
vis[u] = false;
q.pop();
for (int i = head[u]; i; i = e[i].nxt) {
int to = e[i].to;
int w = e[i].w;
if (e[i].val > 0 && dis[to] > dis[u] + w) {
dis[to] = dis[u] + w;
node[to].from = u;
node[to].edge = i;
if (!vis[to]) {
q.push(to);
vis[to] = true;
}
}
}
}
return dis[t] != 0x3f3f3f3f;
}
int cost;
int EK() {
int maxflow = 0;
int mi;
cost = 0;
while (bfs()) {
mi = inf;
for (int i = t; i != s; i = node[i].from) {
mi = min(mi, e[node[i].edge].val);
}
for (int i = t; i != s; i = node[i].from) {
e[node[i].edge].val -= mi;
e[node[i].edge ^ 1].val += mi;
}
maxflow += mi;
cost += mi * dis[t];
}
return maxflow;
}
int u, v, w, val;
signed main() {
n = read(), m = read(), s = read(), t = read();
for (int i = 1; i <= m; i++) {
u = read(), v = read(), val = read(), w = read();
add(u, v, val, w);
add(v, u, 0, -w);
}
printf("%lld\n", EK());
printf("%lld", cost);
return 0;
}