#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define maxn 0x7fffffff
const int inf = 1e9;
int n, m, sta, tag;
struct stu{
int next, to, w;
};
stu edge[100010 * 2];
int deep[10010] = {0};
int edgeNum = -1;
int head[10010] = {0};
int cur[10010] = {0};
int maxFlow = 0;
queue<int>qu;
int read()
{
int x = 0, w = 1;
char ch = getchar();
while(ch <='0' || ch > '9')
{
if(ch == '-') w = -1;
ch = getchar();
}
while(ch <= '9' && ch >= '0')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * w;
}
void add_edge(int from, int to, int w)
{
edge[++edgeNum].next = head[from];
edge[edgeNum].to = to;
edge[edgeNum].w = w;
head[from] = edgeNum;
}
bool bfs(int s, int t)
{
memset(deep, 0x7f, sizeof(deep));
while(!qu.empty()) qu.pop();
for(int i = 1; i <= n; i++)
{
cur[i] = head[i];
}
deep[s] = 0;
qu.push(s);
while(!qu.empty())
{
int now = qu.front();
qu.pop();
for(int i = head[now]; i != -1; i = edge[i].next)
{
int to = edge[i].to;
int w = edge[i].w;
if(deep[to] > inf && w)
{
deep[to] = deep[now] + 1;
qu.push(to);
}
}
}
if(deep[t] < inf) return true;
return false;
}
int dfs(int now, int t, int minn)
{
if(minn == 0 || now == t)
{
return minn;
}
int flow = 0, f;
for(int i = cur[now]; i != -1; i = edge[i].next)
{
cur[now] = i;
int to = edge[i].to;
int w = edge[i].w;
if(deep[to] == deep[now] + 1 && (f = dfs(to, t, min(minn, w))))
{
flow += f;
minn -= f;
edge[i].w -= f;
edge[i ^ 1].w += f;
if(minn == 0) break;
}
}
return flow;
}
void Dinic(int s, int t)
{
while(bfs(s, t))
{
maxFlow += dfs(s, t, maxn);
}
}
int main()
{
n = read();
m = read();
sta = read();
tag = read();
memset(head, -1, sizeof(head));
for(int i = 1; i <= m; i++)
{
int a = read();
int b = read();
int c = read();
add_edge(a, b, c);
add_edge(b, a, 0);
}
Dinic(sta, tag);
printf("%d", maxFlow);
return 0;
}