"""simple docstring"""




class       a_      :




					def __init__(	self						:     Optional[int]  ,						snake_case__						:     Dict  ,						snake_case__						:     Optional[Any]  ,						snake_case__						:     List[Any]     ):
							lowerCAmelCase__        =   None
							lowerCAmelCase__        =   None
							lowerCAmelCase__        =   graph

							self._normalize_graph(__UpperCamelCase  ,						__UpperCamelCase     )
							lowerCAmelCase__        =   len(__UpperCamelCase     )
							lowerCAmelCase__        =   None




					def 						_SCREAMING_SNAKE_CASE						(	self						:     Tuple  ,						snake_case__						:     Optional[Any]  ,						snake_case__						:     List[str]     ):
							if sources is int:
									lowerCAmelCase__        =   [sources]
							if sinks is int:
									lowerCAmelCase__        =   [sinks]

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

							lowerCAmelCase__        =   sources[0]
							lowerCAmelCase__        =   sinks[0]

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

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

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




					def 						_SCREAMING_SNAKE_CASE						(	self						:     Optional[Any]     ):
							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 						_SCREAMING_SNAKE_CASE						(	self						:     List[Any]  ,						snake_case__						:     List[str]     ):
							lowerCAmelCase__        =   algorithm(self     )

class       a_      :




					def __init__(	self						:     Optional[Any]  ,						snake_case__						:     int     ):
							lowerCAmelCase__        =   flow_network
							lowerCAmelCase__        =   flow_network.verticesCount
							lowerCAmelCase__        =   flow_network.sourceIndex
							lowerCAmelCase__        =   flow_network.sinkIndex
							# it's just a reference, so you shouldn't change
							# it in your algorithms, use deep copy before doing that
							lowerCAmelCase__        =   flow_network.graph
							lowerCAmelCase__        =   False




					def 						_SCREAMING_SNAKE_CASE						(	self						:     int     ):
							if not self.executed:
									self._algorithm()
									lowerCAmelCase__        =   True




					def 						_SCREAMING_SNAKE_CASE						(	self						:     int     ):
							pass

class       a_      (     __UpperCamelCase			):




					def __init__(	self						:     Union[str, Any]  ,						snake_case__						:     Tuple     ):
							super().__init__(__UpperCamelCase     )
							# use this to save your result
							lowerCAmelCase__        =   -1




					def 						_SCREAMING_SNAKE_CASE						(	self						:     List[str]     ):
							if not self.executed:
									raise Exception("""You should execute algorithm before using its result!"""     )

							return self.maximum_flow

class       a_      (     __UpperCamelCase			):




					def __init__(	self						:     Dict  ,						snake_case__						:     List[str]     ):
							super().__init__(__UpperCamelCase     )

							lowerCAmelCase__        =   [[0] * self.verticies_count for i in range(self.verticies_count     )]

							lowerCAmelCase__        =   [0] * self.verticies_count
							lowerCAmelCase__        =   [0] * self.verticies_count




					def 						_SCREAMING_SNAKE_CASE						(	self						:     Tuple     ):
							lowerCAmelCase__        =   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
							lowerCAmelCase__        =   [
							    i
							    for i in range(self.verticies_count     )
							    if i != self.source_index and i != self.sink_index
							]

							# move through list
							lowerCAmelCase__        =   0
							while i < len(__UpperCamelCase     ):
									lowerCAmelCase__        =   vertices_list[i]
									lowerCAmelCase__        =   self.heights[vertex_index]
									self.process_vertex(__UpperCamelCase     )
									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(__UpperCamelCase     )     )
											lowerCAmelCase__        =   0
									else:
											i += 1

							lowerCAmelCase__        =   sum(self.preflow[self.source_index]     )




					def 						_SCREAMING_SNAKE_CASE						(	self						:     Optional[int]  ,						snake_case__						:     List[str]     ):
							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(__UpperCamelCase  ,						__UpperCamelCase     )

									self.relabel(__UpperCamelCase     )




					def 						_SCREAMING_SNAKE_CASE						(	self						:     Any  ,						snake_case__						:     Dict  ,						snake_case__						:     List[Any]     ):
							lowerCAmelCase__        =   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 						_SCREAMING_SNAKE_CASE						(	self						:     Optional[int]  ,						snake_case__						:     int     ):
							lowerCAmelCase__        =   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):
											lowerCAmelCase__        =   self.heights[to_index]

							if min_height is not None:
									lowerCAmelCase__        =   min_height + 1


if __name__ == "__main__":
			__lowerCAmelCase    :							List[str]													=						[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    :							Tuple													=						[[0, 7, 0, 0], [0, 0, 6, 0], [0, 0, 0, 8], [9, 0, 0, 0]]

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

			print(F"maximum flow is {maximum_flow}")





"""simple docstring"""




import os







def 							_UpperCAmelCase		(       ):





		"""simple docstring"""




		lowerCAmelCase__        =   os.path.dirname(os.path.realpath(lowerCamelCase__     )     )
		lowerCAmelCase__        =   os.path.join(lowerCamelCase__			,  """triangle.txt"""     )

		with open(lowerCamelCase__     ) as f:
				lowerCAmelCase__        =   f.readlines()

		lowerCAmelCase__        =   []
		for line in triangle:
				lowerCAmelCase__        =   []
				for number in line.strip().split(""" """     ):
						numbers_from_line.append(int(lowerCamelCase__     )     )
				a.append(lowerCamelCase__     )

		for i in range(1			,  len(lowerCamelCase__     )     ):
				for j in range(len(a[i]     )     ):
						lowerCAmelCase__        =   a[i - 1][j] if j != len(a[i - 1]     ) else 0
						lowerCAmelCase__        =   a[i - 1][j - 1] if j > 0 else 0
						a[i][j] += max(lowerCamelCase__			,  lowerCamelCase__     )
		return max(a[-1]     )


if __name__ == "__main__":
			print(solution())




