#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<iostream>
#include<map>
#include<queue>
#include<vector>
#define MaxNode 100001
#define inf 1e9+7
using namespace std;
int n,m,tot=1,head[MaxNode],dis[MaxNode],s,t;
struct Node{
int to;
int nxt;
int w;
} e[MaxNode<<1];
inline int read(){
int f=0,x=0;
char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
inline void add(int u,int v,int w){
e[++tot].to=v;
e[tot].nxt=head[u];
e[tot].w=w;
head[u]=tot;
}
inline bool dinic_bfs(){
queue<int> q;
for(int i=1; i<=n; i++)
dis[i]=0;
dis[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front(); q.pop();
for(int v,i=head[u]; i; i=e[i].nxt){
v=e[i].to;
if(!dis[v]&&e[i].w){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
return dis[t];
}
inline int dinic_dfs(int u,int f){
if(u==t||!f) return f;
int used=0;
for(int i=head[u]; i; i=e[i].nxt){
int v=e[i].to;
if(dis[v]==dis[u]+1&&e[i].w){
int w=dinic_dfs(v,min(e[i].w,f-used));
if(w){
e[i].w-=w;
e[i^1].w+=w;
used+=w;
if(used==f)return f;
}
}
}
if(!used) dis[u]=0;
return used;
}
inline int dinic(){
int ans=0;
while(dinic_bfs())
ans+=dinic_dfs(s,inf);
return ans;
}
int main(){
n=read();m=read();s=read();t=read();
for(int i=1,u,v,w; i<=m; i++){
u=read();v=read();w=read();
add(u,v,w);
add(v,u,0);
}
printf("%d",dinic());
return 0;
}