#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; queue<int>q; int INF=1e9; int n,m,head[10005],cur[10005],ct=1,s,t,d[10005],ans; struct N{ int to,next,w; }edge[200005]; void add(int x,int y,int z) { edge[++ct]=(N){y,head[x],z};head[x]=ct; edge[++ct]=(N){x,head[y],0};head[y]=ct; } bool bfs() { memset(d,0,sizeof d); while(q.size())q.pop(); d[s]=1; q.push(s); while(q.size()) { int x=q.front();q.pop(); for(int i=head[x];i;i=edge[i].next) { int u=edge[i].to; if(!d[u]&&edge[i].w)//残量网络 { d[u]=d[x]+1; q.push(u); } } } return d[t]; } int dfs(int x,int f) { if(x==t)return f;// int res=0,tmp=0; for(int i=cur[x];i;i=edge[i].next) { int u=edge[i].to; if(d[u]==d[x]+1&&edge[i].w) { tmp=dfs(u,min(edge[i].w,f-res)); edge[i].w-=tmp; edge[i^1].w+=tmp; res+=tmp; if(edge[i].w)cur[x]=i; if(res==f)return f;// } } if(!res)d[x]=0;//剪枝 return res; } int main() { scanf("%d%d",&n,&m); scanf("%d%d",&s,&t); int x,y,z; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } while(bfs()) { for(int i=1;i<=n;i++)cur[i]=head[i]; ans+=dfs(s,INF); } printf("%d",ans); return 0; }