#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
using ll = long long;
using ld = long double;
constexpr ll MOD = 1000000007LL;
template <typename T>
constexpr T INF() { return numeric_limits<T>::max() / 10;}
template <typename Functor>
struct fix_type
{
    Functor functor;
    template <typename... Args>
    decltype(auto) operator()(Args&&... args) const& { return functor(functor, std::forward<Args>(args)...); }
};
template <typename Functor>
fix_type<typename std::decay<Functor>::type> fix(Functor&& functor) { return {std::forward<Functor>(functor)}; }



class Flow
{
public:
    using T = ll;
    struct Edge
    {
        Edge(const int from_, const int to_, const int reverse_, const T capacity_, bool is_reverse = false) : from{from_}, to{to_}, reverse{reverse_}, capacity{capacity_}, flow{0}, is_reverse(is_reverse) {}
        int from;
        int to;
        int reverse;
        T capacity;
        T flow;
        bool is_reverse;
    };
    Flow(const int v) : V{v}, edge(v) {}
    void addEdge(const int from, const int to, const T capacity)
    {
        edge[from].push_back(Edge{from, to, (int)edge[to].size(), capacity, false});
        edge[to].push_back(Edge{to, from, (int)edge[from].size() - 1, 0, true});
    }
    T FordFulkerson(const int s, const int t)
    {
        vector<bool> checked(V);
        auto dfs = fix([&](auto&& self, const int pos, const T& flow) -> T {
            if (pos == t) { return flow; }
            checked[pos] = true;
            for (auto& e : edge[pos]) {
                if (not checked[e.to]) {
                    const T res = e.capacity - e.flow;
                    if (res > 0) {
                        const T d = self(self, e.to, min(flow, res));
                        if (d > 0) {
                            e.flow += min(d, res);
                            edge[e.to][e.reverse].flow -= min(d, res);
                            return d;
                        }
                    }
                }
            }
            return 0;
        });
        T flow = 0;
        while (true) {
            for (int i = 0; i < V; i++) { checked[i] = false; }
            const T f = dfs(s, INF<T>());
            if (f == 0) { break; }
            flow += f;
        }
        return flow;
    }
    T Dinic(const int s, const int t)
    {
        T flow = 0;
        while (true) {
            vector<int> level(V, -1);
            auto dfs = fix([&](auto&& self, const int pos, const T& flow) -> T {
                if (pos == t) { return flow; }
                for (auto& e : edge[pos]) {
                    const T res = e.capacity - e.flow;
                    if (res > 0 and level[pos] < level[e.to]) {
                        const T d = self(self, e.to, min(flow, res));
                        if (d > 0) {
                            e.flow += min(d, res);
                            edge[e.to][e.reverse].flow -= min(d, res);
                            return d;
                        }
                    }
                }
                return 0;
            });
            queue<int> q;
            q.push(s);
            level[s] = 0;
            while (not q.empty()) {
                const int v = q.front();
                for (const auto& e : edge[s]) {
                    if (e.capacity > e.flow and level[e.to] < 0) {
                        level[e.to] = level[v] + 1;
                        q.push(e.to);
                    }
                }
            }
            while (true) {
                const T f = dfs(s, INF<T>());
                if (f == 0) { break; }
                flow += f;
            }
        }
    }
    const int V;
    vector<vector<Edge>> edge;
};



// Problem: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A
// Status: Accepted

int main()
{
    std::size_t V, E;
    std::cin >> V >> E;
    Flow f(V);
    for (std::size_t i = 0; i < E; i++) {
        std::size_t u, v;
        int c;
        std::cin >> u >> v >> c;
        f.addEdge(u, v, c);
    }
    std::cout << f.FordFulkerson(0, V - 1) << std::endl;
    return 0;
}



Measured memory_bytes: 3224