#include <bits/stdc++.h>
using namespace std;
using T = int;
const T INF = numeric_limits<T>::max() / 4;
struct MFMC {
struct Edge { int to, nxt; T flow, cap, cost; };
int n;
vector<T> dist, pi;
vector<int> par, graph;
vector<Edge> es;
MFMC(int n) : n(n), pi(n, 0), graph(n, -1) {}
void AddEdge(int a, int b, T cap, T cost) {
auto add = [&](int a, int b, T cap, T cost) {
es.push_back({b, graph[a], 0, cap, cost});
graph[a] = es.size() - 1;
};
add(a, b, cap, cost); add(b, a, 0, -cost);
}
bool dijkstra(int s, int t) {
dist.assign(n, INF); par.assign(n, -1);
priority_queue<pair<T, int>> pq;
dist[s] = 0; pq.emplace(0, s);
while (!pq.empty()) {
auto [d, node] = pq.top(); pq.pop();
if (dist[node] != -d) continue;
for (int ei = graph[node]; ei >= 0; ei = es[ei].nxt) {
const auto &e = es[ei];
T now = dist[node] + pi[node] - pi[e.to] + e.cost;
if (e.flow < e.cap && now < dist[e.to]) {
dist[e.to] = now; par[e.to] = ei;
pq.emplace(-dist[e.to], e.to);
}
}
}
for (int i = 0; i < n; ++i)
pi[i] = min(pi[i] + dist[i], INF);
return par[t] != -1;
}
pair<T, T> Compute(int s, int t) {
T flow = 0, cost = 0;
while (dijkstra(s, t)) {
T now = INF;
for (int node = t; node != s; ) {
int ei = par[node];
now = min(now, es[ei].cap - es[ei].flow);
node = es[ei^1].to;
}
for (int node = t; node != s; ) {
int ei = par[node];
es[ ei ].flow += now;
es[ei^1].flow -= now;
cost += es[ei].cost * now;
node = es[ei^1].to;
}
flow += now;
}
return {flow, cost};
}
// If some costs can be negative, call this before maxflow:
void SetPi(int s) { // (otherwise, leave this out)
pi.assign(n, INF); pi[s] = 0;
int it = n, ch = 1;
while (ch-- && it--)
for (int i = 0; i < n; ++i) if (pi[i] != INF)
for (int ei = graph[i]; ei >= 0; ei = es[ei].nxt) {
const auto& e = es[ei];
T now = pi[i] + e.cost;
if (e.cap && now < pi[e.to])
pi[e.to] = now, ch = 1;
}
assert(it >= 0); // negative cost cycle
}
};
int main() {
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, t; cin >> n >> m >> s >> t;
MFMC F(n);
for (int i = 0; i < m; ++i) {
int a, b, c, k; cin >> a >> b >> c >> k;
F.AddEdge(a - 1, b - 1, c, k);
}
cout << F.Compute(s - 1, t - 1).second << endl;
return 0;
}