#include <iostream>
#include <iomanip>
#include <climits>
#include <limits>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <stack>
#include <string>
#include <functional>
#include <numeric>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <unordered_map>
#include <random>
#define _USE_MATH_DEFINES
#include <cmath>
#include <complex>

using namespace std;

typedef long long int ll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef pair<int, int> P;
typedef pair<ll, ll> Pll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

const int INFL = (int)1e9;
const ll INFLL = (ll)1e18;
const double INFD = numeric_limits<double>::infinity();
#define Loop(i, n) for(int i = 0; i < (int)n; i++)
#define Loopll(i, n) for(ll i = 0; i < (ll)n; i++)
#define Loop1(i, n) for(int i = 1; i <= (int)n; i++)
#define Loopll1(i, n) for(ll i = 1; i <= (ll)n; i++)
#define Loopr(i, n) for(int i = (int)n - 1; i >= 0; i--)
#define Looprll(i, n) for(ll i = (ll)n - 1; i >= 0; i--)
#define Loopr1(i, n) for(int i = (int)n; i >= 1; i--)
#define Looprll1(i, n) for(ll i = (ll)n; i >= 1; i--)
#define Loopitr(itr, container) for(auto itr = container.begin(); itr != container.end(); itr++)
#define printv(vector) Loop(i, vector.size()) { cout << vector[i] << " "; } cout << endl;
#define rnd(d) (ll)((double)d + (d >= 0 ? 0.5 : -0.5))
#define floorsqrt(x) ((ll)sqrt((double)x) + ((ll)sqrt((double)x) * (ll)sqrt((double)x) <= (ll)x ? 0 : -1))
#define ceilsqrt(x) ((ll)sqrt((double)x) + ((ll)x <= (ll)sqrt((double)x) * (ll)sqrt((double)x) ? 0 : 1))
#define ceildiv(a, b) ((ll)a / (ll)b + ((ll)a % (ll)b == 0 ? 0 : 1))
#define bitmanip(m,val) static_cast<bitset<(int)m>>(val)

/*******************************************************/

struct graph_t {
  int n;           // |V|, index begins with 0
  int m;           // |E|
  vector<P> edges; // E
  vector<ll> cost; // cost or distance
  vector<ll> cap;  // capacity
};

class Maxflow {
private:
  struct edgedata {
    int eid, from, to;
    ll cap;
    edgedata* dual_p;
    bool operator<(const edgedata & another) const {
      return (cap != another.cap ? cap > another.cap : eid < another.eid);
    }
  };
  struct node {
    int id; bool done; list<edgedata> edges; ll d;
    bool operator<(const node & another) const {
      return !(d != another.d ? d < another.d : id < another.id);
    }
  };
  vector<node> nodes;
  int n, m;
  int source, sink;
  edgedata* empty_edge;
public:
  Maxflow(graph_t G, int s, int t) {
    n = G.n;
    m = G.m;
    nodes.resize(n);
    Loop(i, n) nodes[i] = { i, false,{}, LLONG_MAX };
    empty_edge = new edgedata;
    Loop(i, G.edges.size()) {
      int a = G.edges[i].first;
      int b = G.edges[i].second;
      nodes[a].edges.push_back({ i, a, b, G.cap[i], empty_edge });
      nodes[b].edges.push_back({ i - m, b, a, 0, &(nodes[a].edges.back()) });
      nodes[a].edges.back().dual_p = &(nodes[b].edges.back());
    }
    source = s;
    sink = t;
    Loop(i, n) nodes[i].edges.sort();
    vector<pair<int, edgedata*>> stk;
    int a; // the node which is focused on
    ll df; // how much flow in one operation
    while (1) {
      Loop(i, n) nodes[i].done = false;
      a = source;
      nodes[source].done = true;
      while (a != sink) {
        int b = -1;
        Loopitr(itr, nodes[a].edges) {
          if (itr->cap > 0) {
            b = itr->to;
            if (nodes[b].done) b = -1;
            else {
              stk.push_back(make_pair(a, &(*itr)));
              nodes[b].done = true;
              break;
            }
          }
        }
        if (b == -1) {
          if (stk.empty()) break;
          a = stk.back().first; stk.pop_back();
        }
        else a = b;
      }
      if (stk.empty()) break;
      df = LLONG_MAX;
      Loop(i, stk.size()) df = min(df, stk[i].second->cap);
      while (stk.size()) {
        stk.back().second->cap -= df;
        stk.back().second->dual_p->cap += df;
        stk.pop_back();
      }
    }
    return;
  }
  vll get_eid_flow() {
    vll ret(m);
    Loop(i, n) {
      Loopitr(itr, nodes[i].edges) {
        if (itr->eid < 0) ret[itr->eid + m] = itr->cap;
      }
    }
    return ret;
  }
  ll get_maxflow() {
    ll ret = 0;
    Loopitr(itr, nodes[sink].edges) {
      if (itr->eid < 0) ret += itr->cap;
    }
    return ret;
  }
};

int main() {
  graph_t G;
  cin >> G.n >> G.m;
  Loop(i, G.m) {
    int u, v;
    ll c;
    cin >> u >> v >> c;
    G.edges.push_back({ u, v });
    G.cap.push_back(c);
  }
  Maxflow maxflow(G, 0, G.n - 1);
  cout << maxflow.get_maxflow() << endl;
  return 0;
}


Measured memory_bytes: 3316