





import argparse
import copy




def 		A_    (					_lowerCAmelCase					)						->			Any:
 UpperCamelCase     : Any	     =       {}

 with open(_lowerCAmelCase					) as f:
  for line in f:
   if line.split()[0] not in dict_of_neighbours:
    UpperCamelCase     : Any	     =       []
    _list.append([line.split()[1], line.split()[2]]					)
    UpperCamelCase     : Any	     =       _list
   else:
    dict_of_neighbours[line.split()[0]].append(
        [line.split()[1], line.split()[2]]					)
   if line.split()[1] not in dict_of_neighbours:
    UpperCamelCase     : str	     =       []
    _list.append([line.split()[0], line.split()[2]]					)
    UpperCamelCase     : List[Any]	     =       _list
   else:
    dict_of_neighbours[line.split()[1]].append(
        [line.split()[0], line.split()[2]]					)

 return dict_of_neighbours




def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase					)						->			List[str]:

 with open(_lowerCAmelCase					) as f:
  UpperCamelCase     : Optional[Any]	     =       f.read(1					)
 UpperCamelCase     : Tuple	     =       start_node

 UpperCamelCase     : Any	     =       []

 UpperCamelCase     : int	     =       start_node

 UpperCamelCase     : List[str]	     =       0
 while visiting not in first_solution:
  UpperCamelCase     : Optional[int]	     =       1_0000
  for k in dict_of_neighbours[visiting]:
   if int(k[1]					) < int(_lowerCAmelCase					) and k[0] not in first_solution:
    UpperCamelCase     : Any	     =       k[1]
    UpperCamelCase     : List[str]	     =       k[0]

  first_solution.append(_lowerCAmelCase					)
  UpperCamelCase     : Optional[Any]	     =       distance_of_first_solution + int(_lowerCAmelCase					)
  UpperCamelCase     : List[Any]	     =       best_node

 first_solution.append(_lowerCAmelCase					)

 UpperCamelCase     : str	     =       0
 for k in dict_of_neighbours[first_solution[-2]]:
  if k[0] == start_node:
   break
  position += 1

 UpperCamelCase     : int	     =       (
     distance_of_first_solution
     + int(dict_of_neighbours[first_solution[-2]][position][1]					)
     - 1_0000
 )
 return first_solution, distance_of_first_solution




def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase					)						->			Optional[Any]:
 UpperCamelCase     : Optional[int]	     =       []

 for n in solution[1:-1]:
  UpperCamelCase     : str	     =       solution.index(_lowerCAmelCase					)
  for kn in solution[1:-1]:
   UpperCamelCase     : List[str]	     =       solution.index(_lowerCAmelCase					)
   if n == kn:
    continue

   UpperCamelCase     : Union[str, Any]	     =       copy.deepcopy(_lowerCAmelCase					)
   UpperCamelCase     : Tuple	     =       kn
   UpperCamelCase     : str	     =       n

   UpperCamelCase     : Union[str, Any]	     =       0

   for k in _tmp[:-1]:
    UpperCamelCase     : List[Any]	     =       _tmp[_tmp.index(_lowerCAmelCase					) + 1]
    for i in dict_of_neighbours[k]:
     if i[0] == next_node:
      UpperCamelCase     : List[str]	     =       distance + int(i[1]					)
   _tmp.append(_lowerCAmelCase					)

   if _tmp not in neighborhood_of_solution:
    neighborhood_of_solution.append(_tmp					)

 UpperCamelCase     : Dict	     =       len(neighborhood_of_solution[0]					) - 1

 neighborhood_of_solution.sort(key=lambda _lowerCAmelCase					: x[index_of_last_item_in_the_list]					)
 return neighborhood_of_solution




def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase					)						->			Optional[Any]:
 UpperCamelCase     : Dict	     =       1
 UpperCamelCase     : Optional[int]	     =       first_solution
 UpperCamelCase     : List[str]	     =       []
 UpperCamelCase     : Any	     =       distance_of_first_solution
 UpperCamelCase     : List[Any]	     =       solution

 while count <= iters:
  UpperCamelCase     : Union[str, Any]	     =       find_neighborhood(_lowerCAmelCase							,       _lowerCAmelCase					)
  UpperCamelCase     : Optional[Any]	     =       0
  UpperCamelCase     : Optional[int]	     =       neighborhood[index_of_best_solution]
  UpperCamelCase     : Dict	     =       len(_lowerCAmelCase					) - 1

  UpperCamelCase     : Union[str, Any]	     =       False
  while not found:
   UpperCamelCase     : Optional[int]	     =       0
   while i < len(_lowerCAmelCase					):
    if best_solution[i] != solution[i]:
     UpperCamelCase     : Optional[Any]	     =       best_solution[i]
     UpperCamelCase     : Dict	     =       solution[i]
     break
    UpperCamelCase     : List[Any]	     =       i + 1

   if [first_exchange_node, second_exchange_node] not in tabu_list and [
       second_exchange_node,
       first_exchange_node,
   ] not in tabu_list:
    tabu_list.append([first_exchange_node, second_exchange_node]					)
    UpperCamelCase     : Optional[Any]	     =       True
    UpperCamelCase     : Union[str, Any]	     =       best_solution[:-1]
    UpperCamelCase     : List[str]	     =       neighborhood[index_of_best_solution][best_cost_index]
    if cost < best_cost:
     UpperCamelCase     : int	     =       cost
     UpperCamelCase     : Any	     =       solution
   else:
    UpperCamelCase     : List[str]	     =       index_of_best_solution + 1
    UpperCamelCase     : Optional[int]	     =       neighborhood[index_of_best_solution]

  if len(_lowerCAmelCase					) >= size:
   tabu_list.pop(0					)

  UpperCamelCase     : Optional[int]	     =       count + 1

 return best_solution_ever, best_cost




def 		A_    (					_lowerCAmelCase=None					)						->			Optional[Any]:
 UpperCamelCase     : Union[str, Any]	     =       generate_neighbours(args.File					)

 UpperCamelCase     : Any	     =       generate_first_solution(
     args.File							,       _lowerCAmelCase					)

 UpperCamelCase     : List[Any]	     =       tabu_search(
     _lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase							,       args.Iterations							,       args.Size							,       )

 print(F"""Best solution: {best_sol}, with total distance: {best_cost}."""					)


if __name__ == "__main__":
    __lowerCamelCase	:					List[str]			  =					argparse.ArgumentParser(description="""Tabu Search""")
    parser.add_argument(
        """-f""",
        """--File""",
        type=str,
        help="""Path to the file containing the data""",
        required=True,
    )
    parser.add_argument(
        """-i""",
        """--Iterations""",
        type=int,
        help="""How many iterations the algorithm should perform""",
        required=True,
    )
    parser.add_argument(
        """-s""", """--Size""", type=int, help="""Size of the tabu list""", required=True
    )

    # Pass the arguments to main method
    main(parser.parse_args())







def 		A_    (					_lowerCAmelCase					)						->			int:
 if n == 1 or not isinstance(_lowerCAmelCase							,       _lowerCAmelCase					):
  return 0
 elif n == 2:
  return 1
 else:
  UpperCamelCase     : Optional[Any]	     =       [0, 1]
  for i in range(2							,       n + 1					):
   sequence.append(sequence[i - 1] + sequence[i - 2]					)

  return sequence[n]



def 		A_    (					_lowerCAmelCase					)						->			int:
 UpperCamelCase     : Any	     =       0
 UpperCamelCase     : List[Any]	     =       2

 while digits < n:
  index += 1
  UpperCamelCase     : Union[str, Any]	     =       len(str(fibonacci(_lowerCAmelCase					)					)					)

 return index



def 		A_    (					_lowerCAmelCase = 1000					)						->			int:
 return fibonacci_digits_index(_lowerCAmelCase					)


if __name__ == "__main__":
    print(solution(int(str(input()).strip())))
