# include <cstdio>
# include <vector>
# include <queue>
# include <algorithm>
using namespace std;
# define FIN "fmcm.in"
# define FOUT "fmcm.out"
const int MAX_N = 351;
const int MAX_M = 12501;
# define f first
# define s second
# define pb push_back
# define mp make_pair
# define inf 0x3f3f3f3f
queue<int> Q;
int Ap[MAX_N];
int C[MAX_N][MAX_N];
int N, M, S, D, i, j;
vector <pair <int, int> > G[MAX_N];
int Dist[MAX_N], T[MAX_N], H[MAX_N], P[MAX_N];
inline int min(int A, int B) {
return A < B ? A : B;
}
void Bellman() {
vector <pair <int, int> > :: iterator it;
memset(Dist, inf, sizeof(Dist));
Dist[S] = 0; Q.push(S); Ap[S] = 1;
while (!Q.empty()) {
Ap[Q.front()] = 0;
for (it = G[Q.front()].begin(); it != G[Q.front()].end(); ++it)
if (Dist[Q.front()] + it -> s < Dist[it -> f] && C[Q.front()][it -> f]) {
Dist[it -> f] = Dist[Q.front()] + it -> s;
if (!Ap[it -> f]) {
Q.push(it -> f);
Ap[it -> f] = 1;
}
}
Q.pop();
}
}
void Up(int i) {
int h = H[i], father = i >> 1, son = i;
while (father && Dist[H[father]] > Dist[h]) {
H[son] = H[father];
P[H[father]] = son;
son = father; father >>= 1;
}
H[son] = h; P[h] = son;
}
void Down(int N, int i) {
int h = H[i], father = i, son = i << 1;
while (son <= N) {
if (son < N && Dist[H[son]] > Dist[H[son + 1]]) ++son;
if (Dist[h] > Dist[H[son]]) {
H[father] = H[son];
P[H[son]] = father;
father = son; son <<= 1;
} else son = N + 1;
}
H[father] = h; P[h] = father;
}
bool Dijkstra() {
int node;
vector <pair <int, int> > :: iterator it;
for (i = 1; i <= N; ++i)
for (it = G[i].begin(); it != G[i].end(); ++it)
if (Dist[i] != inf && Dist[it -> f] != inf)
it -> s = Dist[i] - Dist[it -> f] + it -> s;
memset(T, 0, sizeof(T));
memset(Dist, inf, sizeof(Dist)); Dist[S] = 0;
for (i = 1; i <= N; ++i) {
H[i] = i;
P[i] = i;
}
H[1] = S; P[S] = 1;
H[S] = 1; P[1] = S;
for (i = N; i > 1; --i) {
node = H[1];
for (it = G[node].begin(); it != G[node].end(); ++it)
if (Dist[node] + it -> s < Dist[it -> f] && C[node][it -> f]) {
T[it -> f] = node;
Dist[it -> f] = Dist[node] + it -> s;
Up(P[it -> f]);
}
H[1] = H[i];
Down(i - 1, 1);
}
return Dist[D] == inf ? false : true;
}
int Flow() {
int tcost = 0, flow, cur, cost = Dist[D];
while (Dijkstra()) {
for (cur = D, flow = inf; cur != S; cur = T[cur])
flow = min(flow, C[T[cur]][cur]);
for (cur = D; cur != S; cur = T[cur]) {
C[T[cur]][cur] -= flow;
C[cur][T[cur]] += flow;
}
cost += Dist[D];
tcost += cost * flow;
}
return tcost;
}
int main() {
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
scanf("%d%d%d%d", &N, &M, &S, &D);
int x, y, c, z;
for (i = 1; i <= M; ++i) {
scanf("%d%d%d%d", &x, &y, &c, &z);
C[x][y] = c;
G[x].pb(mp(y, z));
G[y].pb(mp(x, -z));
}
Bellman();
printf("%d\n", Flow());
return 0;
}