#include <bits/stdc++.h>
std::ifstream fin("maxflow.in");
std::ofstream fout("maxflow.out");
const int MAX_N = 1000;
const int INF = 1e9;
struct edge {
int to, cap, flow, rid;
};
struct MaxFlow {
std::vector<edge> g[MAX_N + 1];
bool vis[MAX_N + 1];
int dist[MAX_N + 1];
int ptr[MAX_N + 1];
int n;
void add_edge(int from, int to, int cap) {
g[from].push_back(edge {to, cap, 0, g[to].size()});
g[to].push_back(edge {from, 0, 0, g[from].size() - 1});
}
bool bfs(int s, int t) {
std::queue<int> q;
for (int i = 1; i <= n; i++) {
vis[i] = false;
dist[i] = INF;
}
dist[s] = 0;
q.push(s);
while (!q.empty()) {
int node = q.front();
q.pop();
if (vis[node]) continue;
vis[node] = true;
for (auto & edg : g[node]) {
if (edg.flow < edg.cap && dist[node] + 1 < dist[edg.to]) {
dist[edg.to] = dist[node] + 1;
q.push(edg.to);
}
}
}
return vis[t];
}
int dfs(int node, int dest, int cur_flow) {
if (node == dest)
return cur_flow;
for (; ptr[node] < g[node].size(); ptr[node]++) {
auto & edg = g[node][ptr[node]];
if (edg.flow == edg.cap) continue;
if (dist[edg.to] != dist[node] + 1) continue;
int flow_here = std::min(cur_flow, edg.cap - edg.flow);
flow_here = dfs(edg.to, dest, flow_here);
if (flow_here > 0) {
edg.flow += flow_here;
g[edg.to][edg.rid].flow -= flow_here;
return flow_here;
}
}
}
int max_flow(int s, int t) {
int total_flow = 0;
while (bfs(s, t)) {
for (int i = 1; i <= n; i++)
ptr[i] = 0;
int flow = dfs(s, t, INF);
while (flow > 0) {
total_flow += flow;
flow = dfs(s, t, INF);
}
}
return total_flow;
}
MaxFlow(int n) : n(n) {}
};
int n, m;
void solve() {
fin >> n >> m;
MaxFlow flow(n);
for (int i = 1; i <= m; i++) {
int u, v, c;
fin >> u >> v >> c;
flow.add_edge(u, v, c);
}
fout << flow.max_flow(1, n) << '\n';
}
int main() {
solve();
return 0;
}