#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAX=1e5;
struct node
{
int u,v,w,next;
}ege[MAX];
int head[MAX],tmp,leval[MAX];
int n,k,s,t;
queue<int>q;
void add_ege(int u,int v,int w)
{
ege[tmp].u=u;
ege[tmp].v=v;
ege[tmp].w=w;
ege[tmp].next=head[u];
head[u]=tmp++;
}
bool bfs()
{
memset(leval,0,sizeof(leval));
while(!q.empty())q.pop();
q.push(s);
leval[s]=1;
while(!q.empty())
{
int hd=q.front();
q.pop();
for(int i=head[hd];i!=-1;i=ege[i].next)
{
if(ege[i].w&&!leval[ege[i].v])
{
leval[ege[i].v]=leval[hd]+1;
q.push(ege[i].v);
if(ege[i].v==t)return true;
}
}
}
return false;
}
int dfs(int f,int u)
{
if(u==t)return f;
int d=0,used=0;
for (int i = head[u];i != -1;i = ege[i].next)
{
if(ege[i].w&&leval[u]==leval[ege[i].v]-1)
{
if ((d = dfs(min(f - used, ege[i].w), ege[i].v)))
{
ege[i].w -= d;
ege[i ^ 1].w += d;
used += d;
}
}
}
if(!used)leval[u]=0;
return used;
}
/*bool BFS()
{
memset(leval,0, sizeof(leval));
q[1] = s;
leval[s] = 1;
int hd = 0,tl = 1;
while (hd != tl)
{
hd++;
for(int i = head[q[hd]]; i != -1; i = ege[i].next)
{
if(ege[i].w && !leval[ege[i].v])
{
tl++;
leval[ege[i].v] = leval[q[hd]] + 1;
q[tl] = ege[i].v;
if (ege[i].v == t)
return true;
}
}
}
return false;
}
int DFS(int f, int u)
{
if (u == t)
return f;
int d = 0, used = 0;
for (int i = head[u];i != -1;i = ege[i].next)
{
if (ege[i].w && leval[u] == leval[ege[i].v] - 1)
{
if ((d = DFS(min(f - used, ege[i].w), ege[i].v)))
{
ege[i].w -= d;
ege[i ^ 1].w += d;
used += d;
}
}
}
if (!used)
leval[u] = 0;
return used;
}*/
int dinic()
{
int ans=0;
while(bfs())
{
int d=0;
while((d=dfs(0x3f3f3f,s)))
{
ans+=d;
}
}
return ans;
}
signed main()
{
cin>>n>>k>>s>>t;
memset(head,-1,sizeof(head));
while(k--)
{
int u,v,w;
cin>>u>>v>>w;
add_ege(u,v,w);
add_ege(v,u,0);
}
cout<<dinic()<<endl;
return 0;
}