#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int,int>;

struct edge{int from,to,cost,flow;};

struct Graph {
    vector<vector<P>> to;
    vector<vector<P>> rev;
    vector<edge> e;
    vector<int> visited;
    Graph(int v):e(),to(v),rev(v),visited(v,0){

    }

    void add_edge(int u, int v, int c){
        edge ee;
        ee.from = u; ee.to = v; ee.cost = c; ee.flow = 0;
        e.push_back(ee);
        P p(v,e.size()-1);
        to[u].push_back(p);
        ee.from = v; ee.to = u; ee.cost = 0;
        e.push_back(ee);
        p.first=u; p.second=(e.size()-1);
        rev[v].push_back(p);
    }

    void fillzero(){
        rep(i,visited.size()) visited[i]=0;
    }

    int dfs(int now,int goal, int f){
        visited[0]=1;
        //cout << "now: "<< now << " goal: " << goal << "f:" << f << endl; 
        if(now==goal) return f;

        bool action = false;

        rep(i,to[now].size()){
            int next = to[now][i].first;
            //cout << "to:" << next;
            if(visited[next]==1) {
                //cout << " visited" << endl;
                continue;
            }
            //cout << " in" << endl;
            action = true;
            edge nex_e;
            nex_e = e[to[now][i].second];

            int temp;
            int val;
            temp = nex_e.cost - nex_e.flow;

            if(temp>0){
                //cout << "path" << endl;
                visited[next]=1;
                temp = min(f,temp);
                val = dfs(next,goal,temp);
                if(val>0) {
                    e[to[now][i].second].flow+=val;
                    e[to[now][i].second+1].cost+=val;
                    return val;
                }
            }
        }

        rep(i,rev[now].size()){
            int next = rev[now][i].first;
            //cout << "rev: " << next;
            if(visited[next]==1) {
                //cout << " visited" << endl;
                continue;
            }
            //cout << " in" << endl;
            action = true;
            
            edge nex_e;
            nex_e = e[rev[now][i].second];

            int temp;
            int val;
            temp = nex_e.cost;
            if(temp>0){
                //cout << "path" << endl;
                visited[next]=1;
                temp = min(f,temp);
                val = dfs(next,goal,temp);
                if(val>0){
                    e[rev[now][i].second].cost-=val;
                    return val;
                }
            }
        }

        if(!action){
            //cout << "no action" << endl;
            return -1;
        }
        
        //cout << "no way:" << now << endl;
        return -1;
        
    }

    int total_flow(){
        int res = 0;
        rep(i,to[0].size()){
            res += e[to[0][i].second].flow;
        }
        return res;
    }

    void show(){
        cout << "edge" << endl;
        rep(i,to.size()){
            rep(j,to[i].size()){
                edge ee;
                ee = e[to[i][j].second];
                cout << ee.from<<":" << ee.to<<":" << ee.cost <<":"<< ee.flow << endl;
            }
        }

        cout << "rev" << endl;
        rep(i,rev.size()){
            rep(j,rev[i].size()){
                edge ee;
                ee = e[rev[i][j].second];
                cout << ee.from<<":" << ee.to<<":" << ee.cost <<":"<< ee.flow << endl;
            }
        }
        
    
    }

    
};



int main(){
    int v,e;
    cin >> v >> e;
    Graph g(v);
    int s = 0;
    int t = v-1;
    rep(i,e){
        int u,v,c;
        cin >> u >> v >> c;
        g.add_edge(u,v,c);
    }

    int res = 0;
    while(res!=-1){
        //cout << "dfs" << endl;
        g.fillzero();
        res = g.dfs(s,t,1000);
        //cout << res << endl;
        //g.show();
    }

    //cout << "ans" << endl;
    cout << g.total_flow() << endl;
}


Measured memory_bytes: 3192