rt
#include <queue>
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <forward_list>
#define N 1205
#define M 120005
#define IINF 0x3FFFFFFF
#define INF 0x3FFFFFFFFFFFFFFF
long long ex[N];
int h[N], gap[N], n, m, s, t, lv;
struct ed {int v, w, f;} gr[M << 1];
std::forward_list<int> mp[N], b[N];
int read()
{
int x = 0;
char c, f = 1;
while (!isdigit(c = getchar()) && c != '-');
if (c == '-')c = getchar(), f = -1;
while (isdigit(c))
{
x = x * 10 + (c ^ '0');
c = getchar();
}
return x * f;
}
bool bfs()
{
std::queue<int> q;
std::fill(h + 1, h + n + 1, IINF);
q.push(t);
h[t] = 0;
while (!q.empty())
{
const int u = q.front();
q.pop();
for (const int i : mp[u])
{
const int& v = gr[i].v;
if (gr[i ^ 1].w && h[v] > h[u] + 1)
h[v] = h[u] + 1, q.push(v);
}
}
return h[s] != IINF;
}
bool push(int u)
{
for (const int& i : mp[u])
{
const int& v = gr[i].v, &w = gr[i].w;
if (!w || (u != s && h[u] != h[v] + 1) || h[v] >= IINF)
continue;
long long k = std::min((long long)w, ex[u]);
if (v != s && v != t && !ex[v])
b[h[v]].push_front(v), lv = std::max(lv, h[v]);
ex[u] -= k; ex[v] += k; gr[i].w -= k; gr[i ^ 1].w += k;
if (!ex[u])return false;
}
return true;
}
void relabel(int u)
{
h[u] = IINF;
for (const int& i : mp[u])
{
const int& v = gr[i].v, &w = gr[i].w;
if (w)h[u] = std::min(h[u], h[v]);
}
if (++h[u] < n)
{
b[h[u]].push_front(u);
lv = std::max(lv, h[u]);
++gap[h[u]];
}
}
int selc()
{
while (b[lv].empty() && lv >= 0)--lv;
return lv >= 0 ? b[lv].front() : 0;
}
int main()
{
int u;
n = read(); m = read(); s = read(); t = read();
for (int i = 1, t = 1, u, v, w; i <= m; ++i)
{
u = read(); v = read(); w = read();
gr[++t] = {v, w};
mp[u].push_front(t);
gr[++t] = {u, 0};
mp[v].push_front(t);
}
bfs();
h[s] = n;
ex[s] = INF;
for (int i = 1; i <= n; ++i)
if (h[i] < IINF)++gap[h[i]];
push(s);
while (u = selc())
{
b[lv].pop_front();
if (push(u))
{
if (!--gap[h[u]])
for (int i = 1; i <= n; ++i)
if (i != s && i != t && h[i] > h[u] && h[i] <= n)
h[i] = n + 1;
relabel(u);
}
}
printf("%lld", ex[t]);
}