#include <bits/stdc++.h>
#define N 405
#define INF 0x3f3f3f3f
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
struct edge {
int v;
int cap, flow;
int cost;
};
int n;
vector<edge> e;
vector<int>g[N];
int dist[N], pot[N];
int f[N];
bool vis[N];
int par[N];
bool n2dijkstra = false;
///mcmf(int n) : n(n), g(n), dist(n), pot(n), f(n), vis(n), par(n) {}
void add_edge(int u, int v, int cap, int cost) {
int k = e.size();
e.push_back({v, cap, 0, cost});
e.push_back({u, cap, cap, -cost});
g[u].push_back(k);
g[v].push_back(k ^ 1);
}
pair<int, long long> solve(int s, int t) {
int flow = 0;
long long cost = 0;
while(true) {
memset(dist,INF,sizeof(dist));
memset(vis, false,sizeof(vis));
dist[s] = 0;
f[s] = numeric_limits<int>::max();
if(n2dijkstra) {
while(true) {
int x = -1; int d = numeric_limits<int>::max();
for(int i = 1; i <= n; i++) {
if(!vis[i] && dist[i] < d) {
x = i;
d = dist[x];
}
}
if(x == -1) break;
vis[x] = true;
for(int i : g[x]) {
int d2 = d + e[i].cost + pot[x] - pot[e[i].v];
if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) {
dist[e[i].v] = d2;
f[e[i].v] = min(f[x], e[i].cap - e[i].flow);
par[e[i].v] = i;
}
}
}
}else {
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int,int> > > Q;
Q.push({0, s});
while(!Q.empty()) {
int d; int x;
tie(d, x) = Q.top(); Q.pop();
if(vis[x]) continue;
vis[x] = true;
for(int i : g[x]) {
int d2 = d + e[i].cost + pot[x] - pot[e[i].v];
if(!vis[e[i].v] && e[i].flow < e[i].cap && d2 < dist[e[i].v]) {
dist[e[i].v] = d2;
f[e[i].v] = min(f[x], e[i].cap - e[i].flow);
par[e[i].v] = i;
Q.push({d2, e[i].v});
}
}
}
}
if(!vis[t]) break;
for(int i = 1; i <= n; i++) {
dist[i] += pot[i] - pot[s];
}
cost += 1ll*dist[t] * f[t];
flow += f[t];
int x = t;
while(x != s) {
e[par[x]].flow += f[t];
e[par[x] ^ 1].flow -= f[t];
x = e[par[x] ^ 1].v;
}
swap(dist,pot);
}
return {flow, cost};
}
int main()
{
int i,x,y,c,z,m,s,t;
fin>>n>>m>>s>>t;
while(m--)
{
fin>>x>>y>>c>>z;
add_edge(x,y,c,z);
}
fout<<solve(s,t).second;
return 0;
}