#include <bits/stdc++.h>
using namespace std;
struct MinCostMaxFlow {
struct Edge{
int to, cap;
int flow;
int cost;
};
static const int MAX_V = 355;
static const int MAX_E = 12505 * 2;
static const int INF = 1e9 + 7;
static const int MAX_COST = 1e9 + 7; // change to ll if it is exceeded in FB
int sz = 0;
Edge e[MAX_E];
vector<int> g[MAX_V];
int dp[MAX_V];
pair<int, int> prev[MAX_V];
int phi[MAX_V];
void addEdge(int v, int to, int cap, int cost){
//cost *= -1;
g[v].push_back(sz);
e[sz++] = { to, cap, 0, cost };
g[to].push_back(sz);
e[sz++] = { v, 0, 0, -cost };
}
void calcPhi(int start) {
// FB for calculating phi, add vertex q and q->v for all v with cost 0
for (int i = 0; i < MAX_V; ++i) phi[i] = MAX_COST;
phi[start] = 0;
for (int k = 0; k < MAX_V; k++) {
for (int v = 0; v < MAX_V; v++) {
for (int to : g[v]) {
Edge &ed = e[to];
if (ed.cap == ed.flow) continue;
phi[ed.to] = min(phi[ed.to], phi[v] + ed.cost);
}
}
}
}
long long find(int start, int finish, int required_flow) {
calcPhi(start);
long long ans = 0;
while (required_flow) {
for (int i = 0; i < MAX_V; i++) dp[i] = INF, prev[i] = { -1, -1 };
dp[start] = 0;
set< pair<int, int> > se;
se.insert({ 0, start });
while (!se.empty()) {
auto aux = *se.begin();
int dist = aux.first, v = aux.second;
se.erase(se.begin());
for (int to : g[v]) {
auto ed = e[to];
if (ed.flow < ed.cap && dp[ed.to] > dp[v] + ed.cost - phi[ed.to] + phi[v]) {
prev[ed.to] = { v, to };
se.erase({ dp[ed.to], ed.to });
dp[ed.to] = dp[v] + ed.cost - phi[ed.to] + phi[v];
se.insert({ dp[ed.to], ed.to });
}
}
}
if (dp[finish] == INF) {
return ans;
}
int max_flow = required_flow;
int v = finish;
while (1) {
auto now = prev[v];
if (now.first == -1) break;
max_flow = min(max_flow, e[now.second].cap - e[now.second].flow);
v = now.first;
}
ans += (dp[finish] + phi[finish]) * (long long)max_flow;
v = finish;
while (1) {
auto now = prev[v];
if (now.first == -1) break;
e[now.second].flow += max_flow;
e[now.second ^ 1].flow -= max_flow;
v = now.first;
}
required_flow -= max_flow;
// recalc phi
int min_phi = 0;
for (int i = 0; i < MAX_V; ++i) {
if (dp[i] == INF) {
min_phi = min(min_phi, phi[i]);
} else {
phi[i] += dp[i];
}
}
for (int i = 0; i < MAX_V; ++i) {
if (dp[i] == INF) {
phi[i] -= min_phi;
}
}
//
}
return ans;
}
} mcmf;
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
int n, m, S, D, x, y, c, z;
scanf("%d%d%d%d", &n, &m, &S, &D);
for(int i = 1; i <= m; i ++) {
scanf("%d%d%d%d", &x, &y, &c, &z);
mcmf.addEdge(x, y, c, z);
}
printf("%d", mcmf.find(S, D, 1e9));
return 0;
}