#include <bits/stdc++.h>
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
using ll = long long;
class Flow {
const ll flow_max = 1e18;
struct Edge {
int from, to;
ll c;
Edge(int a, int b, ll _c) : from(a), to(b), c(_c) {}
};
vector <Edge> edges;
int n, s, t, k;
vector <int> lvl, rem;
vector <vector <int>> g;
bool bfs() {
fill(lvl.begin(), lvl.end(), 0);
queue <int> q; q.push(s); lvl[s] = 1;
while(!q.empty()) {
int top = q.front(); q.pop();
for(int id : g[top])
if(!lvl[edges[id].to] && edges[id].c) {
lvl[edges[id].to] = lvl[top] + 1;
q.push(edges[id].to);
}
}
return lvl[t];
}
public:
Flow(int _n, int _s, int _t) : n(_n), s(_s), t(_t), k(0), lvl(n + 1, 0), rem(n + 1, 0), g(n + 1) {}
void add_edge(int u, int v, int w) {
edges.emplace_back(u, v, w);
edges.emplace_back(v, u, 0);
g[u].push_back(k++);
g[v].push_back(k++);
}
ll dfs(int u, ll flow) {
if(flow == 0) return 0;
if(u == t) return flow;
for(int& cid = rem[u]; cid < (int)g[u].size(); cid++) {
int id = g[u][cid];
int v = edges[id].to;
if(!edges[id].c || lvl[v] != lvl[u] + 1) continue;
ll f = dfs(v, min(flow, edges[id].c));
edges[id].c -= f;
edges[id ^ 1].c += f;
return f;
}
return 0;
}
ll dinic() {
ll f = 0;
while(bfs()) {
fill(rem.begin(), rem.end(), 0);
while(ll flow = dfs(s, flow_max))
f += flow;
}
return f;
}
};
int main()
{
int n, m, u, v, w;
fin >> n >> m;
Flow f(n, 1, n);
for(int i = 0; i < m; i++) {
fin >> u >> v >> w;
f.add_edge(u, v, w);
}
fout << f.dinic();
return 0;
}