// -*- c++ -*-
#include <iostream>
#include <fstream>

#include <list_graph.h>
//#include <smart_graph.h>
#include <dimacs.h>
#include <time_measure.h>
#include <for_each_macros.h>
#include <bfs_iterator.h>

using namespace hugo;

int main() {
  typedef ListGraph Graph; 
  typedef Graph::Node Node;
  typedef Graph::NodeIt NodeIt;
  typedef Graph::Edge Edge;
  typedef Graph::EdgeIt EdgeIt;
  typedef Graph::OutEdgeIt OutEdgeIt;

  Graph G;
  Node s, t;
  Graph::EdgeMap<int> cap(G);
  readDimacsMaxFlow(std::cin, G, s, t, cap);
  Graph::NodeMap<OutEdgeIt> pred(G);
  Timer ts;
  {
    ts.reset();
    Graph::NodeMap<bool> reached(G);
    reached.set(s, true);
    pred.set(s, INVALID);
    std::queue<Node> bfs_queue;
    bfs_queue.push(t);
    while (!bfs_queue.empty()) {
      Node v=bfs_queue.front();	
      bfs_queue.pop();
      OutEdgeIt e;
      for(G.first(e,v); G.valid(e); G.next(e)) {
	Node w=G.head(e);
	if (!reached[w]) {
	  bfs_queue.push(w);
	  reached.set(w, true);
	  pred.set(w, e);
	}
      }
    }

    std::cout << ts << std::endl;
  }

  {
    ts.reset();      
    BfsIterator< Graph, Graph::NodeMap<bool> > bfs(G);
    bfs.pushAndSetReached(s);
    pred.set(s, INVALID);
    while (!bfs.finished()) { 
      ++bfs; 
      if (G.valid(bfs) && bfs.isBNodeNewlyReached()) 
	pred.set(bfs.bNode(), bfs);
    }
    std::cout << ts << std::endl;
  }

  return 0;
}
