#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 352
#define INF 13000000
using namespace std;
int n, m, source, dest;
int flux, fcost;
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pq;
vector<int> arcs[MAXN];
int costs[MAXN][MAXN];
int caps[MAXN][MAXN];
int bf_res[MAXN];
void bellman_ford()
{
int curr_node;
int viz[n+1], i, next_node;
queue<int> q;
memset(viz, 0, sizeof(viz));
memset(bf_res, INF, sizeof(bf_res));
q.push(source);
viz[source] = 1;
bf_res[source] = 0;
while(!q.empty())
{
curr_node = q.front();
viz[curr_node] = 0;
for(i = 0; i<arcs[curr_node].size(); ++i)
if(caps[curr_node][arcs[curr_node][i]])
{
next_node = arcs[curr_node][i];
if(bf_res[curr_node] + costs[curr_node][next_node] >= bf_res[next_node])
continue;
bf_res[next_node] = bf_res[curr_node] + costs[curr_node][next_node];
if (!viz[next_node])
{
viz[next_node] = 1;
q.push(next_node);
}
}
q.pop();
}
}
bool dijkstra()
{
int i, next_node, next_cost, curr_node;
int d_working[n+2], d_final[n+2], parents[n+2], d_old[n+2];
memset(d_working, INF, sizeof(d_working));
memset(d_final, 0, sizeof(d_final));
memset(parents, 0, sizeof(parents));
memcpy(d_old, bf_res, sizeof(d_final));
d_working[source] = d_final[source] = 0;
pq.push(make_pair(d_working[source], source));
while (!pq.empty())
{
int curr_cost = pq.top().first;
int curr_node = pq.top().second;
pq.pop();
if (d_working[curr_node] != curr_cost)
continue;
for (i=0; i<arcs[curr_node].size(); ++i)
if(caps[curr_node][arcs[curr_node][i]])
{
next_node = arcs[curr_node][i];
next_cost = d_working[curr_node] + costs[curr_node][next_node] +
d_old[curr_node] - d_old[next_node];
if (next_cost < d_working[next_node])
{
d_working[next_node] = next_cost;
d_final[next_node] = d_final[curr_node] + costs[curr_node][next_node];
parents[next_node] = curr_node;
pq.push(make_pair(next_cost, next_node));
}
}
}
if(!parents[dest])
return false;
memcpy(d_old, d_final, sizeof(d_working));
int minf = INF, mincost = 0;
for(curr_node = dest; curr_node != source; curr_node = parents[curr_node])
{
if(minf > caps[parents[curr_node]][curr_node])
minf = caps[parents[curr_node]][curr_node];
mincost += costs[parents[curr_node]][curr_node];
}
flux += minf;
fcost += minf * d_final[dest];
for(curr_node = dest; curr_node != source; curr_node = parents[curr_node])
{
caps[parents[curr_node]][curr_node] -= minf;
caps[curr_node][parents[curr_node]] += minf;
}
return true;
}
int main()
{
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
int x, y;
scanf("%d%d%d%d", &n, &m, &source, &dest);
for(int i=0; i<m; ++i)
{
scanf("%d%d", &x, &y);
arcs[x].push_back(y);
arcs[y].push_back(x);
scanf("%d%d", &caps[x][y], &costs[x][y]);
costs[y][x] = -costs[x][y];
}
bellman_ford();
while(dijkstra());
printf("%d\n", fcost);
fclose(stdin);
fclose(stdout);
return 0;
}