#include <bits/stdc++.h>
using namespace std;
const int Nmax=355;
int cost[Nmax][Nmax],C[Nmax][Nmax],dist[Nmax],tata[Nmax],n,m,s,d,real_dist[Nmax],dij_dist[Nmax];
vector<int>G[Nmax];
queue<int>Q;
vector<int>::iterator it;
bitset<Nmax>viz;
const int inf=0x3f3f3f3f;
int costflux;
struct cmp
{
bool operator()(const pair<int,int> &a,const pair<int,int> &b)
{
return dij_dist[a.second]>dij_dist[b.second];
}
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp>Heap;
bool bellmanford()
{
memset(dist,inf,sizeof(dist));
dist[s]=0;
viz[s]=1;
Q.push(s);
while(Q.size())
{
int nod=Q.front();
Q.pop();
viz[nod]=0;
for(it=G[nod].begin();it!=G[nod].end();it++)
{
if(C[nod][*it] && dist[*it]>dist[nod]+cost[nod][*it])
{
dist[*it]=dist[nod]+cost[nod][*it];
tata[*it]=nod;
if(viz[*it]==0)
{
viz[*it]=1;
Q.push(*it);
}
}
}
}
if(dist[d]==inf) return 0;
return 1;
}
bool dijkstra()
{
memset(dij_dist,inf,sizeof(dij_dist));
dij_dist[s]=real_dist[s]=0;
Heap.push(make_pair(dij_dist[s],s));
while(Heap.size())
{
int nod=Heap.top().second,cst=Heap.top().first;
Heap.pop();
if(dij_dist[nod]!=cst) continue;
for(it=G[nod].begin();it!=G[nod].end();it++)
{
if(C[nod][*it])
{
int step=dij_dist[nod]+cost[nod][*it]+dist[nod]-dist[*it];
if(step<dij_dist[*it])
{
real_dist[*it]=real_dist[nod]+cost[nod][*it];
dij_dist[*it]=step;
tata[*it]=nod;
Heap.push(make_pair(dij_dist[*it],*it));
}
}
}
}
memcpy(dist,real_dist,sizeof(dist));
if(dij_dist[d]==inf) return 0;
int fmin=inf,i;
for(i=d;i!=s;i=tata[i])
{
fmin=min(fmin,C[tata[i]][i]);
}
for(i=d;i!=s;i=tata[i])
{
C[tata[i]][i]-=fmin;
C[i][tata[i]]+=fmin;
}
costflux+=real_dist[d]*fmin;
return 1;
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
int x,y,c,z,fmin,i;
//fin>>n>>m>>s>>d;
scanf("%d%d%d%d",&n,&m,&s,&d);
while(m--)
{
//fin>>x>>y>>c>>z;
scanf("%d%d%d%d",&x,&y,&c,&z);
G[x].push_back(y);
G[y].push_back(x);
C[x][y]=c;
cost[x][y]=z;
cost[y][x]=-z;
}
bellmanford();
while(dijkstra());
printf("%d",costflux);
}