#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = , INF = 0x7fffffff;
int d[maxn], head[maxn];
int n, m, s, t;
struct edge{
int u, v, f, c, next;
}Node[*maxn]; void add(int u, int v, int c, int f, int i)
{
Node[i].u = u;
Node[i].v = v;
Node[i].f = f;
Node[i].c = c;
Node[i].next = head[u];
head[u] = i;
} int bfs()
{
queue<int> Q;
mem(d,);
Q.push(s);
d[s] = ;
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i=head[u]; i!=-; i=Node[i].next)
{
edge e = Node[i];
if(!d[e.v] && e.c > e.f)
{
d[e.v] = d[e.u] + ;
Q.push(e.v);
}
}
} return d[t] != ;
} int dfs(int u, int cap)
{
// cout<< u << " " << cap <<endl;
if(u == t)
return cap;
for(int i=head[u]; i!= -; i=Node[i].next)
{
edge e = Node[i];
if(d[e.v] == d[e.u] + && e.c > e.f)
{
int V = dfs(e.v, min(cap, e.c - e.f));
if(V > ){
Node[i].f += V;
Node[i^].f -= V;
return V;
}
}
}
return ;
}
int Dinic()
{
int ans = ;
while(bfs())
{
while(int l = dfs(s,INF))
ans += l;
}
return ans;
} int main()
{
mem(head,-);
cin>> n >> m >> s >> t;
int cnt = ;
for(int i=; i<m; i++)
{
int u, v, w;
cin>> u >> v >> w;
add(u, v, w, , cnt++);
add(v, u, , , cnt++);
}
cout<< Dinic() <<endl; return ;
}