#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<queue> #include<set> #define maxint (2147483647) #define l(a) ((a)<<1) #define r(a) ((a)<<1|1) #define b(a) (2<<(a)) #define rep(i,a,b) for(int i=a;i<=(b);i++) #define repe(i,e) for(edge*e=fir[i];e;e=e->next) #define clr(a) memset(a,0,sizeof(a)) typedef long long ll; using namespace std; int readint(){ int t=0,f=1;char c=getchar(); while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); } while(isdigit(c)){ t=(t<<3)+(t<<1)+c-'0'; c=getchar(); } return t*f; } const int maxn=10009,maxm=200009; int n,m,S,T,d[maxn]; struct edge{ int v,w; edge*next,*r; }e[maxm],*fir[maxn],*cur[maxn],*pt=e; void add(int u,int v,int w){ pt->v=v;pt->w=w;pt->next=fir[u]; fir[u]=pt++; } void addedge(int u,int v,int w){ add(u,v,w);add(v,u,0); fir[u]->r=fir[v];fir[v]->r=fir[u]; } bool bfs(){ queue<int>Q;Q.push(S); clr(d);d[S]=1; while(!Q.empty()){ int x=Q.front();Q.pop(); repe(x,e){ if(e->w&&!d[e->v]){ d[e->v]=d[x]+1;Q.push(e->v); } } } if(d[T]) rep(i,1,n) cur[i]=fir[i]; return d[T]; } int dfs(int x,int w){ if(x==T||!w) return w; int f=0; for(edge*&e=cur[x];e;e=e->next){ if(e->w&&d[e->v]==d[x]+1){ int g=dfs(e->v,min(e->w,w)); if(g>0){ f+=g; e->w-=g;e->r->w+=g; if(!(w-=g)) break; } } } return f; } int main(){ //freopen("#input.txt","r",stdin); //freopen("#output.txt","w",stdout); n=readint();m=readint();S=readint();T=readint(); rep(i,1,m){ int u=readint(),v=readint(),w=readint(); addedge(u,v,w); } int ans=0; while(bfs()) ans+=dfs(S,maxint); printf("%d ",ans); //fclose(stdin); //fclose(stdout); return 0; }