#include<bits/stdc++.h>
#define int long long
const int N = 2e5+5;
using namespace std;
struct node
{
int to,nxt,w;
} e[N];
int n,m,cnt=1,s,t,depth[N];
int head[N];
int cur[N];
bool bfs()
{
memset(depth,0,sizeof depth);
queue<int>q;
q.push(s);
depth[s] = 1;
while(!q.empty())
{
int r = q.front();
q.pop();
for(int i=head[r]; i; i = e[i].nxt)
{
if(e[i].w > 0 && depth[e[i].to] == 0)
{
depth[e[i].to] = depth[r]+1;
q.push(e[i].to);
}
}
}
if(depth[t] == 0)
return 0;
return 1;
}
int dfs(int u,int dis)
{
if(u == t) return dis;
for(int &i=cur[u]; i; i=e[i].nxt)
{
if(depth[e[i].to] == depth[u]+1 && e[i].w != 0) {
int di = dfs(e[i].to,min(dis,e[i].w));
if(di > 0)
{
e[i].w -= di;
e[i^1].w+= di;
return di;
}
}
}
return 0;
}
int Dinic()
{
int ans = 0;
while(bfs())
{
for(int i=1; i<=n; i++)
cur[i] = head[i];
int f;
while(f = dfs(s,0x3f3f3f3f3f3f))
{
ans+=f;
}
}
return ans;
}
void add(int u,int v,int w)
{
e[++cnt] = {v,head[u],w};
head[u] = cnt;
}
void _add(int u,int v,int w)
{
add(u,v,w);
add(v,u,0);
}
signed main()
{
cin>>n>>m>>s>>t;
for(int i=1,u,v,w; i<=m; i++)
{
cin>>u>>v>>w;
_add(u,v,w);
}
cout<<Dinic();
return 0;
}