#ifndef NIMI_GRAPH
#define NIMI_GRAPH

#include <vector>

namespace nimi {
  struct base_edge {
    int from;
    int to;
    base_edge(int from, int to) : from(from), to(to) {  }
  };

  template<class T>
    struct edge : public base_edge {
      T val;
      edge(int from, int to, T v) : base_edge(from, to), val(v) {  }
    };

  template<>
    struct edge<void> : public base_edge {
      edge(int from, int to) : base_edge(from , to) {  }
    };
  
  struct maxflow_edge : public base_edge {
    std::size_t cap;
    std::size_t rev;
    maxflow_edge(int from, int to, std::size_t cap, std::size_t rev)
      : base_edge(from, to), cap(cap), rev(rev) {  }
  };

  template<class T>
  struct directed_graph : public std::vector<std::vector<edge<T>>> {
    directed_graph(std::size_t n): std::vector<std::vector<edge<T>>>(n) { }
    void add_edge(const edge<T>& e) { this->at(e.from).push_back(e); }
  };

  template<class T>
  struct undirected_graph : public std::vector<std::vector<edge<T>>> {
    undirected_graph(std::size_t n): std::vector<std::vector<edge<T>>>(n) { }
    void add_edge(const edge<T>& e) { this->at(e.from).push_back(e); this->at(e.to).push_back(edge<T>(e.to, e.from, e.val)); }
  };

  struct maxflow_graph : public std::vector<std::vector<maxflow_edge>> {
    maxflow_graph(std::size_t n): std::vector<std::vector<maxflow_edge>>(n) {  }
    void add_edge(int from, int to, std::size_t cap, std::size_t rev_cap = 0) {
      this->at(from).push_back(maxflow_edge(from, to, cap, this->at(to).size()));
      this->at(to).push_back(maxflow_edge(to, from, rev_cap, this->at(from).size() - 1));
    }
  };
}

#endif

#ifndef NIMI_GRAPH_MAXFLOW_DINIC
#define NIMI_GRAPH_MAXFLOW_DINIC

#include <limits>
#include <queue>
#include <vector>
#include <functional>

namespace nimi {
  std::size_t dinic(nimi::maxflow_graph& g, std::size_t s, std::size_t t) {
    std::size_t inf = std::numeric_limits<std::size_t>::max();
    std::size_t ans = 0;
    std::size_t n = g.size();

    std::vector<int> level(n);
    std::vector<std::size_t> iter(n);

    std::function<void(void)> g_level = [&]() {
      level.assign(n, -1);
      std::queue<int> que;
      que.push(s);
      level[s] = 0;
      while(!que.empty()) {
        int v = que.front();
        que.pop();
        for(const auto& e: g[v]) {
          if(e.cap > 0 && level[e.to] == -1) {
            level[e.to] = level[e.from] + 1;
            que.push(e.to);
          }
        }
      }
    };

    std::function<std::size_t(int, std::size_t)> dinic_dfs = 
      [&](int v, std::size_t f) {
        if(v == t) return f;
        std::size_t now = f;

        for(std::size_t& i = iter[v];i < g[v].size();i++) {
          auto& e = g[v][i];
          if(e.cap > 0 && level[e.to] > level[e.from]) {
            std::size_t ff = dinic_dfs(e.to, std::min(now, e.cap));
            e.cap -= ff;
            g[e.to][e.rev].cap += ff;
            now -= ff;
          }
        }
        return f - now;
      };

    while(1) {
      g_level();
      if(level[t] < 0) break;
      std::size_t f;
      iter.assign(n, 0);
      while((f = dinic_dfs(s, inf)) > 0) {
        ans += f;
      }
    }

    return ans;
  }
} 

#endif

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);(i)++)
#define all(x) x.begin(),x.end()

int main() {
  std::size_t N,M;
  cin >> N >> M;
  nimi::maxflow_graph g(N);
  for(int i = 0;i < M;i++) {
    int a, b;
    cin >> a >> b;
    std::size_t c;
    cin >> c;
    g.add_edge(a, b, c);
  }

  cout << dinic(g, 0, N - 1) << endl;

}



Measured memory_bytes: 3200