#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
using namespace std;
struct edge
{
int next, to, flow;
}a[2000020];
int n, m;
int s, t;
int cnt(0);
int head[1000010];
int dep[1000010];
int maxf(0);
void addedge(int xi, int yi, int fi)
{
a[cnt].to = yi;
a[cnt].next = head[xi];
a[cnt].flow = fi;
head[xi] = cnt++;
}
bool bfs(int s)
{
queue<int> q;
while (!q.empty())q.pop();
memset(dep, -1, sizeof(dep));
dep[s] = 1;
q.push(s);
while (!q.empty())
{
int t = q.front();
q.pop();
for (int i = head[t]; i != -1; i = a[i].next)
{
int v = a[i].to;
int f = a[i].flow;
if ((f > 0) && (dep[v] == -1))
{
dep[v] = dep[t] + 1;
q.push(v);
}
}
}
return dep[t] != -1;
}
int dfs(int u, int dist)
{
if (u == t)return dist;
for (int i = head[u]; i != -1; i = a[i].next)
{
int v = a[i].to;
int f = a[i].flow;
if ((dep[v] == dep[u] + 1) && (f != 0))
{
int df(dfs(v, min(dist, f)));
if (df > 0)
{
a[i].flow -= df;
a[i ^ 1].flow += df;
return df;
}
}
}
return 0;
}
void dinic()
{
maxf = 0;
int nowf(0);
while (bfs(s))
{
nowf = INF;
while (nowf)
{
nowf = dfs(s, INF);
maxf += nowf;
}
}
}
int main()
{
memset(head, -1, sizeof(head));
scanf("%d%d", &m, &n);
s = 1, t = n;
for (int i = 1; i <= m; i++)
{
int x, y, f;
scanf("%d%d%d", &x, &y, &f);
addedge(x, y, f);
addedge(y, x, 0);
}
dinic();
printf("%d", maxf);
return 0;
}