class 		a__						:

					def __init__(    self      :       Optional[Any],_A      :       str,_A      :       List[str],_A      :       int    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		str				      =    None
							SCREAMING_SNAKE_CASE_  :		Any				      =    None
							SCREAMING_SNAKE_CASE_  :		Any				      =    graph

							self._normalize_graph(_A,_A    )
							SCREAMING_SNAKE_CASE_  :		str				      =    len(_A    )
							SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    None

					def 				__UpperCamelCase   (    self      :       List[Any],_A      :       int,_A      :       Any    ):







							"""simple docstring"""






							if sources is int:
									SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    [sources]
							if sinks is int:
									SCREAMING_SNAKE_CASE_  :		List[str]				      =    [sinks]

							if len(_A    ) == 0 or len(_A    ) == 0:
									return

							SCREAMING_SNAKE_CASE_  :		List[str]				      =    sources[0]
							SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    sinks[0]

							# make fake vertex if there are more
							# than one source or sink
							if len(_A    ) > 1 or len(_A    ) > 1:
									SCREAMING_SNAKE_CASE_  :		List[str]				      =    0
									for i in sources:
											max_input_flow += sum(self.graph[i]    )

									SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    len(self.graph    ) + 1
									for room in self.graph:
											room.insert(0,0    )
									self.graph.insert(0,[0] * size    )
									for i in sources:
											SCREAMING_SNAKE_CASE_  :		int				      =    max_input_flow
									SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    0

									SCREAMING_SNAKE_CASE_  :		Dict				      =    len(self.graph    ) + 1
									for room in self.graph:
											room.append(0    )
									self.graph.append([0] * size    )
									for i in sinks:
											SCREAMING_SNAKE_CASE_  :		str				      =    max_input_flow
									SCREAMING_SNAKE_CASE_  :		Dict				      =    size - 1

					def 				__UpperCamelCase   (    self      :       Optional[int]    ):







							"""simple docstring"""






							if self.maximum_flow_algorithm is None:
									raise Exception("You need to set maximum flow algorithm before."    )
							if self.source_index is None or self.sink_index is None:
									return 0

							self.maximum_flow_algorithm.execute()
							return self.maximum_flow_algorithm.getMaximumFlow()






					def 				__UpperCamelCase   (    self      :       List[str],_A      :       Tuple    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		Tuple				      =    algorithm(self    )







class 		a__						:

					def __init__(    self      :       Union[str, Any],_A      :       str    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		int				      =    flow_network
							SCREAMING_SNAKE_CASE_  :		str				      =    flow_network.verticesCount
							SCREAMING_SNAKE_CASE_  :		Dict				      =    flow_network.sourceIndex
							SCREAMING_SNAKE_CASE_  :		List[str]				      =    flow_network.sinkIndex
							# it's just a reference, so you shouldn't change
							# it in your algorithms, use deep copy before doing that
							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    flow_network.graph
							SCREAMING_SNAKE_CASE_  :		List[Any]				      =    False

					def 				__UpperCamelCase   (    self      :       Any    ):







							"""simple docstring"""






							if not self.executed:
									self._algorithm()
									SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    True






					def 				__UpperCamelCase   (    self      :       Optional[Any]    ):







							"""simple docstring"""






							pass







class 		a__						(					A__					):

					def __init__(    self      :       int,_A      :       Union[str, Any]    ):







							"""simple docstring"""






							super().__init__(_A    )
							# use this to save your result
							SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    -1






					def 				__UpperCamelCase   (    self      :       Tuple    ):







							"""simple docstring"""






							if not self.executed:
									raise Exception("You should execute algorithm before using its result!"    )

							return self.maximum_flow







class 		a__						(					A__					):

					def __init__(    self      :       List[str],_A      :       int    ):







							"""simple docstring"""






							super().__init__(_A    )

							SCREAMING_SNAKE_CASE_  :		int				      =    [[0] * self.verticies_count for i in range(self.verticies_count    )]

							SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    [0] * self.verticies_count
							SCREAMING_SNAKE_CASE_  :		Tuple				      =    [0] * self.verticies_count

					def 				__UpperCamelCase   (    self      :       Tuple    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		Dict				      =    self.verticies_count

							# push some substance to graph
							for nextvertex_index, bandwidth in enumerate(self.graph[self.source_index]    ):
									self.preflow[self.source_index][nextvertex_index] += bandwidth
									self.preflow[nextvertex_index][self.source_index] -= bandwidth
									self.excesses[nextvertex_index] += bandwidth

							# Relabel-to-front selection rule
							SCREAMING_SNAKE_CASE_  :		List[str]				      =    [
							    i
							    for i in range(self.verticies_count    )
							    if i != self.source_index and i != self.sink_index
							]

							# move through list
							SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    0
							while i < len(_A    ):
									SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    vertices_list[i]
									SCREAMING_SNAKE_CASE_  :		Dict				      =    self.heights[vertex_index]
									self.process_vertex(_A    )
									if self.heights[vertex_index] > previous_height:
											# if it was relabeled, swap elements
											# and start from 0 index
											vertices_list.insert(0,vertices_list.pop(_A    )    )
											SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    0
									else:
											i += 1

							SCREAMING_SNAKE_CASE_  :		Union[str, Any]				      =    sum(self.preflow[self.source_index]    )

					def 				__UpperCamelCase   (    self      :       Union[str, Any],_A      :       Optional[int]    ):







							"""simple docstring"""






							while self.excesses[vertex_index] > 0:
									for neighbour_index in range(self.verticies_count    ):
											# if it's neighbour and current vertex is higher
											if (
											    self.graph[vertex_index][neighbour_index]
											    - self.preflow[vertex_index][neighbour_index]
											    > 0
											    and self.heights[vertex_index] > self.heights[neighbour_index]
											):
													self.push(_A,_A    )

									self.relabel(_A    )

					def 				__UpperCamelCase   (    self      :       str,_A      :       Union[str, Any],_A      :       int    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		List[str]				      =    min(
							    self.excesses[from_index],self.graph[from_index][to_index] - self.preflow[from_index][to_index],)
							self.preflow[from_index][to_index] += preflow_delta
							self.preflow[to_index][from_index] -= preflow_delta
							self.excesses[from_index] -= preflow_delta
							self.excesses[to_index] += preflow_delta






					def 				__UpperCamelCase   (    self      :       Tuple,_A      :       List[Any]    ):







							"""simple docstring"""






							SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    None
							for to_index in range(self.verticies_count    ):
									if (
									    self.graph[vertex_index][to_index]
									    - self.preflow[vertex_index][to_index]
									    > 0
									) and (min_height is None or self.heights[to_index] < min_height):
											SCREAMING_SNAKE_CASE_  :		Any				      =    self.heights[to_index]

							if min_height is not None:
									SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    min_height + 1


if __name__ == "__main__":
		__lowerCamelCase					:	int       =  [0]
		__lowerCamelCase					:	str       =  [3]
		# graph = [
		#     [0, 0, 4, 6, 0, 0],
		#     [0, 0, 5, 2, 0, 0],
		#     [0, 0, 0, 0, 4, 4],
		#     [0, 0, 0, 0, 6, 6],
		#     [0, 0, 0, 0, 0, 0],
		#     [0, 0, 0, 0, 0, 0],
		# ]
		__lowerCamelCase					:	Any       =  [[0, 7, 0, 0], [0, 0, 6, 0], [0, 0, 0, 8], [9, 0, 0, 0]]

		# prepare our network
		__lowerCamelCase					:	List[str]       =  FlowNetwork(graph, entrances, exits)
		# set algorithm
		flow_network.set_maximum_flow_algorithm(PushRelabelExecutor)
		# and calculate
		__lowerCamelCase					:	str       =  flow_network.find_maximum_flow()

		print(f'''maximum flow is {maximum_flow}''')

from functools import lru_cache




@lru_cache
def       _snake_case	(   lowerCAmelCase							:   int	):
		"""simple docstring"""







		if num < 0:
				raise ValueError("Number should not be negative."	)

		return 1 if num in (0, 1) else num * factorial(num - 1	)


if __name__ == "__main__":
		import doctest

		doctest.testmod()
