#include <bits/stdc++.h>
using namespace std;
using T = int;
const T INF = numeric_limits<T>::max() / 4;
struct MFMC {
struct Edge { int from, to; T flow, cap, cost; };
int n;
vector<T> dist, pi;
vector<int> par; vector<vector<int>> graph;
vector<Edge> es;
MFMC(int n) : n(n), pi(n, 0), par(n, -1), graph(n) {}
void AddEdge(int a, int b, T cap, T cost) {
auto add = [&](int a, int b, T cap, T cost) {
es.push_back({a, b, 0, cap, cost});
graph[a].push_back(es.size() - 1);
};
add(a, b, cap, cost); add(b, a, 0, -cost);
}
bool relax(int ei) {
const auto &e = es[ei];
if (dist[e.from] == INF) return false;
T now = dist[e.from] + pi[e.from] - pi[e.to] + e.cost;
if (e.flow < e.cap && now < dist[e.to]) {
dist[e.to] = now; par[e.to] = ei;
return true;
}
return false;
}
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()) {
T d; int node; tie(d, node) = pq.top(); pq.pop();
// auto [d, node] = pq.top(); pq.pop();
if (dist[node] != -d) continue;
for (auto ei : graph[node])
if (relax(ei))
pq.emplace(-dist[es[ei].to], es[ei].to);
}
for (int i = 0; i < n; ++i) {
assert(dist[i] >= 0);
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 ei = par[t]; ei != -1; ei = par[es[ei].from])
now = min(now, es[ei].cap - es[ei].flow);
assert(now > 0);
for (int ei = par[t]; ei != -1; ei = par[es[ei].from]) {
es[ ei ].flow += now;
es[ei^1].flow -= now;
cost += es[ei].cost * now;
}
flow += now;
}
return {flow, cost};
}
// If some costs can be negative, call this before maxflow:
void SetPi(int s) { // (otherwise, leave this out)
dist.assign(n, INF); dist[s] = 0;
int it = n, ch = 1;
while (ch-- && it--)
for (int ei = 0; ei < (int)es.size(); ++ei)
ch |= relax(ei);
assert(it >= 0); // negative cost cycle
swap(pi, dist);
}
void SetPi2(int s) {
pi.assign(n, INF);
vector<int> q;
vector<bool> inq(n, false);
auto push = [&](int node, T d) {
if (pi[node] <= d) return;
pi[node] = d;
if (!inq[node]) inq[node] = true, q.push_back(node);
};
push(s, 0);
for (int i = 0; i < (int)q.size(); ++i) {
for (auto ei : graph[q[i]]) {
const auto& e = es[ei];
if (e.cap) push(e.to, pi[q[i]] + e.cost);
}
}
}
};
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);
}
F.SetPi2(s - 1);
cout << F.Compute(s - 1, t - 1).second << endl;
return 0;
}