#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define N 50001
#define M 500001
int n,m,x,y,cap;
struct dinic{
struct graph{
int tot,head[M];
struct edge{
int next;
int to,dis;
}ed[M];
void addEdge(int from,int to,int dis){
ed[tot].next=head[from];
ed[tot].to=to,ed[tot].dis=dis;
head[from]=tot;
tot++;
}
void init(){
tot=0;
memset(ed,0,sizeof(ed));
memset(head,0,sizeof(head));
}
}l;
int deep[N];
int cur[N];
int s,t;
void addEdge(int v,int u,int cap){
l.addEdge(v,u,cap);
l.addEdge(u,v,0);
}
int dfs(int v,int f){
if(v==t)return f;
for(int& i=cur[v];i!=0;i=l.ed[i].next){
int u=l.ed[i].to,cap=l.ed[i].dis;
if((deep[u]==deep[v]+1)&&(cap!=0)){
int di=dfs(u,min(f,cap));
if(di>0){
l.ed[i].dis-=di;
l.ed[i^1].dis+=di;
return di;
}
}
}
return 0;
}
bool bfs(){
queue<int>q;
memset(deep,0,sizeof(deep));
deep[s]=1;
q.push(s);
while(!q.empty()){
int v=q.front();
q.pop();
for(int i=l.head[v];i!=0;i=l.ed[i].next){
int u=l.ed[i].to,cap=l.ed[i].dis;
if(deep[u]==0&&cap>0){
deep[u]=deep[v]+1;
q.push(u);
}
}
}
return deep[t];
}
int execute(){
int Max=0;
while(bfs()){
for(int i=1;i<=n;i++)cur[i]=l.head[i];
int k=dfs(s,0x7fffffff);
while(k){
Max+=k;
k=dfs(s,0x7fffffff);
}
}
l.init();
return Max;
}
}di;
void input(){
cin>>n>>m>>di.s>>di.t;
for(int i=1;i<=m;i++){
cin>>x>>y>>cap;
di.addEdge(x,y,cap);
}
}
int main(){
input();
cout<<di.execute()<<endl;
}