docs: def max_flow(self, source, sink, display = None, algo = 'DFS'):
          '''
          API: max_flow(self, source, sink, display=None)
          Description:
          Finds maximum flow from source to sink by a depth-first search based
          augmenting path algorithm.
          Pre:
              Assumes a directed graph in which each arc has a 'capacity'
              attribute and for which there does does not exist both arcs (i,j)
              and (j, i) for any pair of nodes i and j.
          Input:
              source: Source node name.
              sink: Sink node name.
              display: Display mode.
          Post:
              The 'flow" attribute of each arc gives a maximum flow.
          '''
          if display is not None:
              old_display =  self.attr['display']
              self.attr['display'] = display
          nl = self.get_node_list()
          # set flow of all edges to 0
          for e in self.edge_attr:
              self.edge_attr[e]['flow'] = 0
              if 'capacity' in self.edge_attr[e]:
                  capacity = self.edge_attr[e]['capacity']
                  self.edge_attr[e]['label'] = str(capacity)+'/0'
              else:
                  self.edge_attr[e]['capacity'] = INF
                  self.edge_attr[e]['label'] = 'INF/0'
          while True:
              # find an augmenting path from source to sink using DFS
              if algo == 'DFS':
                  q = Stack()
              elif algo == 'BFS':
                  q = Queue()
              q.push(source)
              pred = {source:None}
              explored = [source]
              for n in nl:
                  self.get_node(n).set_attr('color', 'black')
              for e in self.edge_attr:
                  if self.edge_attr[e]['flow'] == 0:
                      self.edge_attr[e]['color'] = 'black'
                  elif self.edge_attr[e]['flow']==self.edge_attr[e]['capacity']:
                      self.edge_attr[e]['color'] = 'red'
                  else:
                      self.edge_attr[e]['color'] = 'green'
              self.display()
              while not q.isEmpty():
                  current = q.peek()
                  q.remove(current)
                  if current == sink:
                      break
                  out_neighbor = self.neighbors[current]
                  in_neighbor = self.in_neighbors[current]
                  neighbor = out_neighbor+in_neighbor
                  for m in neighbor:
                      if m in explored:
                          continue
                      self.get_node(m).set_attr('color', 'yellow')
                      if m in out_neighbor:
                          self.set_edge_attr(current, m, 'color', 'yellow')
                          available_capacity = (
                              self.get_edge_attr(current, m, 'capacity')-
                              self.get_edge_attr(current, m, 'flow'))
                      else:
                          self.set_edge_attr(m, current, 'color', 'yellow')
                          available_capacity=self.get_edge_attr(m, current, 'flow')
                      self.display()
                      if available_capacity > 0:
                          self.get_node(m).set_attr('color', 'blue')
                          if m in out_neighbor:
                              self.set_edge_attr(current, m, 'color', 'blue')
                          else:
                              self.set_edge_attr(m, current, 'color', 'blue')
                          explored.append(m)
                          pred[m] = current
                          q.push(m)
                      else:
                          self.get_node(m).set_attr('color', 'black')
                          if m in out_neighbor:
                              if (self.get_edge_attr(current, m, 'flow') ==
                                  self.get_edge_attr(current, m, 'capacity')):
                                  self.set_edge_attr(current, m, 'color', 'red')
                              elif self.get_edge_attr(current, m, 'flow') == 0:
                                  self.set_edge_attr(current, m, 'color', 'black')
                              #else:
                              #    self.set_edge_attr(current, m, 'color', 'green')
                          else:
                              if (self.get_edge_attr(m, current, 'flow') ==
                                  self.get_edge_attr(m, current, 'capacity')):
                                  self.set_edge_attr(m, current, 'color', 'red')
                              elif self.get_edge_attr(m, current, 'flow') == 0:
                                  self.set_edge_attr(m, current, 'color', 'black')
                              #else:
                              #    self.set_edge_attr(m, current, 'color', 'green')
                      self.display()
              # if no path with positive capacity from source sink exists, stop
              if sink not in pred:
                  break
              # find capacity of the path
              current = sink
              min_capacity = 'infinite'
              while True:
                  m = pred[current]
                  if (m,current) in self.edge_attr:
                      arc_capacity = self.edge_attr[(m, current)]['capacity']
                      flow = self.edge_attr[(m, current)]['flow']
                      potential = arc_capacity-flow
                      if min_capacity == 'infinite':
                          min_capacity = potential
                      elif min_capacity > potential:
                          min_capacity = potential
                  else:
                      potential = self.edge_attr[(current, m)]['flow']
                      if min_capacity == 'infinite':
                          min_capacity = potential
                      elif min_capacity > potential:
                          min_capacity = potential
                  if m == source:
                      break
                  current = m
              # update flows on the path
              current = sink
              while True:
                  m = pred[current]
                  if (m, current) in self.edge_attr:
                      flow = self.edge_attr[(m, current)]['flow']
                      capacity = self.edge_attr[(m, current)]['capacity']
                      new_flow = flow+min_capacity
                      self.edge_attr[(m, current)]['flow'] = new_flow
                      if capacity == INF:
                          self.edge_attr[(m, current)]['label'] = \
                              'INF' + '/'+str(new_flow)
                      else:
                          self.edge_attr[(m, current)]['label'] = \
                              str(capacity)+'/'+str(new_flow)
                      if new_flow==capacity:
                          self.edge_attr[(m, current)]['color'] = 'red'
                      else:
                          self.edge_attr[(m, current)]['color'] = 'green'
                      self.display()
                  else:
                      flow = self.edge_attr[(current, m)]['flow']
                      capacity = self.edge_attr[(current, m)]['capacity']
                      new_flow = flow-min_capacity
                      self.edge_attr[(current, m)]['flow'] = new_flow
                      if capacity == INF:
                          self.edge_attr[(current, m)]['label'] = \
                              'INF' + '/'+str(new_flow)
                      else:
                          self.edge_attr[(current, m)]['label'] = \
                              str(capacity)+'/'+str(new_flow)
                      if new_flow==0:
                          self.edge_attr[(current, m)]['color'] = 'red'
                      else:
                          self.edge_attr[(current, m)]['color'] = 'green'
                      self.display()
                  if m == source:
                      break
                  current = m
          if display is not None:
              self.attr['display'] = old_display