#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
using namespace std;
const int nmax = 350;
const int inf = 2000000000;
struct Muchie {
int to, rev, flow, cap, cost;
};
int n, m, sursa, drena;
vector <Muchie> g[1 + nmax];
queue<int> q;
int dist[1 + nmax];
void bellmanford() {
fill(dist + 1, dist + n + 1, inf);
dist[sursa] = 0;
q.push(sursa);
while(!q.empty()) {
int from = q.front();
for(int k = 0; k < g[from].size(); ++ k) {
Muchie e = g[from][k];
if(e.flow < e.cap && dist[e.to] > dist[from] + e.cost) {
dist[e.to] = dist[from] + e.cost;
q.push(e.to);
}
}
q.pop();
}
}
struct Nod {
int nod, cost;
bool operator> (Nod other) const {
return (cost > other.cost);
}
};
priority_queue<Nod, vector<Nod>, greater<Nod> > pq;
int prevnod[1 + nmax], prevmuchie[1 + nmax], plusflow[1 + nmax], distdij[1 + nmax];
bitset <1 + nmax> viz;
void dijkstra() {
fill(distdij + 1, distdij + n + 1, inf);
viz = 0;
distdij[sursa] = 0;
plusflow[sursa] = inf;
pq.push({sursa, 0});
while(!pq.empty()) {
int from = pq.top().nod;
viz[from] = 1;
for(int k = 0; k < g[from].size(); ++ k) {
Muchie e = g[from][k];
if(viz[e.to] == 0 && e.flow < e.cap && distdij[e.to] > distdij[from] + e.cost + dist[from] - dist[e.to]) {
distdij[e.to] = distdij[from] + e.cost + dist[from] - dist[e.to];
pq.push({e.to, distdij[e.to]});
prevnod[e.to] = from;
prevmuchie[e.to] = k;
plusflow[e.to] = min(plusflow[from], e.cap - e.flow);
}
}
pq.pop();
}
}
int mincostflow() {
int flow = 0, flowcostmin = 0;
bellmanford();
dijkstra();
while(distdij[drena] < inf){
int deltaflow = plusflow[drena];
flow += deltaflow;
for(int to = drena; to != sursa; to = prevnod[to]) {
Muchie &e = g[prevnod[to]][prevmuchie[to]];
e.flow += deltaflow;
g[e.to][e.rev].flow -= deltaflow;
flowcostmin += deltaflow * e.cost;
}
for(int i = 1; i <= n; ++ i) {
dist[i] += distdij[i];
}
dijkstra();
}
return flowcostmin;
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
scanf("%d%d%d%d", &n, &m, &sursa, &drena);
for(int i = 1; i <= m; ++ i) {
int from, to, cap, cost;
scanf("%d%d%d%d", &from, &to, &cap, &cost);
g[from].push_back({to, g[to].size(), 0, cap, cost});
g[to].push_back({from, g[from].size() - 1, 0, 0, -cost});
}
printf("%d\n", mincostflow());
return 0;
}