#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e5+5;
int n,m,s,t;
struct edges
{
int to,f,next;
}edge[maxn<<1];
int head[maxn],gap[maxn],d[maxn],pre[maxn],last[maxn],cnt;
void add(int from,int to,int f)
{
edge[cnt].to=to;
edge[cnt].f=f;
edge[cnt].next=head[from];
head[from]=cnt++;
}
void bfs(void)
{
memset(d,-1,sizeof(d));
d[t]=0;
gap[0]++;
queue<int>q;
q.push(t);
while(q.size()){
int tmp=q.front();q.pop();
for(int i=head[tmp];~i;i=edge[i].next){
int to=edge[i].to;
if(d[to]==-1&&edge[i].f){
d[to]=d[tmp]+1;
gap[d[to]]++;
q.push(to);
}
}
}
}
int max_flow(void)
{
bfs();
int flow=0;
int x=s;
for(int i=1;i<=n;i++) last[i]=head[i];
while(d[s]<n){
if(x==t){
int neck=0,tmp=INF;
for(int i=s;i!=t;i=edge[last[i]].to){
if(tmp>edge[last[i]].f){
tmp=edge[last[i]].f;neck=i;
}
}
for(int i=s;i!=t;i=edge[last[i]].to){
edge[last[i]].f-=tmp;
edge[last[i]^1].f+=tmp;
}
flow+=tmp;x=neck;
}
int i;
for(i=last[x];~i;i=edge[i].next)
if(d[x]==d[edge[i].to]+1&&edge[i].f)break;
if(i!=-1){
last[x]=i;
pre[edge[i].to]=x;
x=edge[i].to;
}else{
int minl=INF;
if(!--gap[d[x]]) break;
last[x]=head[x];
for(int i=head[x];~i;i=edge[i].next){
if(minl>d[edge[i].to]&&edge[i].f) minl=d[edge[i].to];
}
d[x]=minl+1;
gap[d[x]]++;
if(x!=s) x=pre[x];
}
}
return flow;
}
int main(void)
{
memset(head,-1,sizeof(head));
cin>>n>>m>>s>>t;
int x,y,z;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
add(x,y,z);add(y,x,0);
}
cout<<max_flow()<<endl;
}