#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int NMAX = 1005;
int n;
int c[NMAX][NMAX];
vector <int> graph[NMAX];
class InputReader {
public:
InputReader() {}
InputReader(const char *file_name) {
input_file = fopen(file_name, "r");
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
inline InputReader &operator >>(int &n) {
while(buffer[cursor] < '0' || buffer[cursor] > '9') {
advance();
}
n = 0;
while('0' <= buffer[cursor] && buffer[cursor] <= '9') {
n = n * 10 + buffer[cursor] - '0';
advance();
}
return *this;
}
private:
FILE *input_file;
static const int SIZE = 1 << 17;
int cursor;
char buffer[SIZE];
inline void advance() {
++ cursor;
if(cursor == SIZE) {
cursor = 0;
fread(buffer, SIZE, 1, input_file);
}
}
} fin("maxflow.in");
inline void read() {
int m = 0;
fin >> n >> m;
int a, b, cost;
while (m --) {
fin >> a >> b >> cost;
c[a][b] += cost;
}
int i, j;
for (i = 1; i <= n; ++ i)
for (j = i + 1; j <= n; ++ j)
if (c[i][j] || c[j][i]) {
graph[i].push_back(j);
graph[j].push_back(i);
}
}
int h[NMAX];
int e[NMAX];
int h_apps[NMAX]; //h_apparences
queue <int> _queue;
bool in_queue[NMAX];
inline void push(int node1, int node2) {
int to_be_pushed = min(e[node1], c[node1][node2]);
if (to_be_pushed) {
e[node1] -= to_be_pushed;
e[node2] += to_be_pushed;
c[node1][node2] -= to_be_pushed;
c[node2][node1] += to_be_pushed;
if (!in_queue[node2]) {
_queue.push(node2);
in_queue[node2] = true;
}
}
}
inline void gap(int check_h) {
if (!h_apps[check_h]) {
for (int i = 1; i <= n; ++ i)
if (h[i] > check_h) {
h[i] = n + 1;
h_apps[h[i]] --;
}
}
}
inline void relabel(int node) {
++ h[node];
h_apps[h[node] - 1] --;
h_apps[h[node]] ++;
gap(h[node] - 1);
}
int iter[NMAX];
void discharge(int node) {
while (1) {
for (int i = 0; i < graph[node].size(); ++ i)
if (h[node] > h[graph[node][i]]) {
push(node, graph[node][i]);
if (!e[node]) {
iter[node] = i;
return ;
}
}
for (int i = 0; i < iter[node]; ++ i)
if (h[node] > h[graph[node][i]]) {
push(node, graph[node][i]);
if (!e[node]) {
iter[node] = i;
return ;
}
}
iter[node] = 0;
relabel(node);
}
}
int push_relabel_maxflow(int s, int t) {
_queue.push(s);
in_queue[s] = true;
h[s] = n;
for (auto it: graph[s])
e[s] += c[s][it];
int node, steps = 0;
while (!_queue.empty()) {
node = _queue.front();
_queue.pop();
in_queue[node] = false;
++ steps;
if (node == t || (node == s && steps > 1))
continue ;
discharge(node);
}
return e[t];
}
int main()
{
ofstream cout("maxflow.out");
read();
cout << push_relabel_maxflow(1, n) << '\n';
//cin.close();
cout.close();
return 0;
}