#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
ifstream in("maxflow.in");
ofstream out("maxflow.out");
#define cin in
#define cout out
struct Dinic
{
int n;
struct EDGE
{
int from, to, cap, prev;
};
vector<EDGE> edges;
vector<int> dist, last;
Dinic (int _n)
{
n = _n + 1;
last.resize(n, -1);
dist.resize(n);
}
void addEdge(int u, int v, int c)
{
edges.push_back({u, v, c, last[u]});
last[u] = edges.size() - 1;
edges.push_back({v, u, 0, last[v]});
last[v] = edges.size() - 1;
}
bool bfs(int s, int d)
{
dist.assign(n, inf);
queue<int> q;
q.push(s);
dist[s] = 0;
while (!q.empty())
{
int x = q.front();
q.pop();
for (int i = last[x]; i != -1; i = edges[i].prev)
{
if (edges[i].cap && dist[edges[i].to] == inf)
{
dist[edges[i].to] = dist[x] + 1;
q.push(edges[i].to);
}
}
}
return dist[d] != inf;
}
int dfs(int nod, int d, int push)
{
if (push == 0)
return 0;
if (nod == d)
return push;
int ans = 0;
for (int i = last[nod]; i != -1; i = edges[i].prev)
{
if (push == 0)
break;
if (dist[edges[i].to] > dist[nod] && edges[i].cap)
{
int x = dfs(edges[i].to, d, min(push, edges[i].cap));
push -= x;
ans += x;
edges[i].cap -= x;
edges[i ^ 1].cap += x;
}
}
return ans;
}
int maxFlow(int s, int d)
{
int ans = 0;
while (bfs(s, d))
ans += dfs(s, d, inf);
return ans;
}
};
int main()
{
int n, m;
cin >> n >> m;
Dinic g(n);
for (int i = 0; i < m; i ++)
{
int u, v, cap;
cin >> u >> v >> cap;
g.addEdge(u, v, cap);
}
cout << g.maxFlow(1, n) << '\n';
}