#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100005;
struct Dinic
{
struct edge
{
int from , to , flow , cost;
};
vector< edge> edges;
vector< int> dist , adia[NMAX], tata;
int n , s, d, sum = 0;
void addedge(int fr , int to , int flux , int p)
{
edges.push_back({fr,to,flux,p});
adia[fr].push_back(edges.size()-1);
edges.push_back({to,fr,0,-p});
adia[to].push_back(edges.size()-1);
}
bool bellman()
{
queue<int>q;
q.push(s);
fill(dist.begin(),dist.end(),1e9);
fill(tata.begin(),tata.end(),-1);
vector<int>viz(n+1,0);
dist[s] = 0 ;
viz[s] =1 ;
tata[s]=0;
while(!q.empty())
{
int nod = q.front();
q.pop();
viz[nod] = 0;
for(int i :adia[nod])
{
edge e = edges[i];
if(!e.flow)continue;
if(tata[e.to]==-1)
{
dist[e.to] = dist[nod] + e.cost;
tata[e.to] = i;
viz[e.to] = 1;
q.push(e.to);
}
else
{
if(dist[e.to] > dist[nod] + e.cost && tata[nod]!=(i^1))
{
dist[e.to] = dist[nod] + e.cost;
if(!viz[e.to])q.push(e.to);
viz[e.to] = 1;
tata[e.to] = i;
}
}
}
}
return (dist[d]!=1e9);
}
int dfs(int nod , int flux)
{
if(nod == s)
return flux;
else
{
edge &e = edges[tata[nod]];
int f = dfs(e.from , min(flux,e.flow));
sum += f * e.cost;
e.flow -= f;
edges[tata[nod]^1].flow+=f;
return f;
}
}
int GetFlow()
{
int x = 0;
while(bellman())
{
int flux = dfs(d , 1e9);
x += flux;
}
return sum;
}
Dinic(int n1,int s1, int d1)
{
tata = dist = vector<int>(n+2,0);
s = s1 ;
n = n1;
d = d1;
}
};
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
int n,m,s1,d1;
cin>>n>>m>>s1>>d1;
Dinic g(n,s1,d1);
for(int i=1;i<=m;i++)
{
int a,b,c,d;
cin>>a>>b>>c>>d;
g.addedge(a,b,c,d);
}
int res=g.GetFlow();
cout<<res;
return 0;
}