
import glob
import os
from typing import Dict, List, Union

import torch

from diffusers.utils import is_safetensors_available


if is_safetensors_available():
     import safetensors.torch

from huggingface_hub import snapshot_download

from diffusers import DiffusionPipeline, __version__
from diffusers.schedulers.scheduling_utils import SCHEDULER_CONFIG_NAME
from diffusers.utils import CONFIG_NAME, DIFFUSERS_CACHE, ONNX_WEIGHTS_NAME, WEIGHTS_NAME


class 					a_					(lowerCAmelCase__      ):




       def __init__(       self					):
         self.register_to_config()
         super().__init__()




       def 							__UpperCamelCase    (       self				,				snake_case_				,				snake_case_					):


         if dicta == dicta:
           return True
         else:
           _lowerCAmelCase			,   _lowerCAmelCase    :					Any							=   self._remove_meta_keys(__lowerCAmelCase					)
           _lowerCAmelCase			,   _lowerCAmelCase    :					Dict							=   self._remove_meta_keys(__lowerCAmelCase					)
           if configa == configa:
             print(f'Warning !: Mismatch in keys {meta_keysa} and {meta_keysa}.'					)
             return True
         return False




       def 							__UpperCamelCase    (       self				,				snake_case_					):
         _lowerCAmelCase    :					Optional[int]							=   []
         _lowerCAmelCase    :					Any							=   config_dict.copy()
         for key in config_dict.keys():
           if key.startswith("""_"""					):
             temp_dict.pop(__lowerCAmelCase					)
             meta_keys.append(__lowerCAmelCase					)
         return (temp_dict, meta_keys)




       @torch.no_grad()
       def 							__UpperCamelCase    (       self				,				snake_case_				,				**snake_case_					):
         _lowerCAmelCase    :					Any							=   kwargs.pop("""cache_dir"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					List[str]							=   kwargs.pop("""resume_download"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					Any							=   kwargs.pop("""force_download"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					int							=   kwargs.pop("""proxies"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					int							=   kwargs.pop("""local_files_only"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					Optional[Any]							=   kwargs.pop("""use_auth_token"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					Any							=   kwargs.pop("""revision"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					Union[str, Any]							=   kwargs.pop("""torch_dtype"""				,				__lowerCAmelCase					)
         _lowerCAmelCase    :					Union[str, Any]							=   kwargs.pop("""device_map"""				,				__lowerCAmelCase					)

         _lowerCAmelCase    :					Optional[Any]							=   kwargs.pop("""alpha"""				,				0.5					)
         _lowerCAmelCase    :					List[Any]							=   kwargs.pop("""interp"""				,				__lowerCAmelCase					)

         print("""Received list"""				,				__lowerCAmelCase					)
         print(f'Combining with alpha={alpha}, interpolation mode={interp}'					)

         _lowerCAmelCase    :					int							=   len(__lowerCAmelCase					)
         # Ignore result from model_index_json comparision of the two checkpoints
         _lowerCAmelCase    :					List[str]							=   kwargs.pop("""force"""				,				__lowerCAmelCase					)

         # If less than 2 checkpoints, nothing to merge. If more than 3, not supported for now.
         if checkpoint_count > 3 or checkpoint_count < 2:
           raise ValueError(
               """Received incorrect number of checkpoints to merge. Ensure that either 2 or 3 checkpoints are being"""
               """ passed."""					)

         print("""Received the right number of checkpoints"""					)
         # chkpt0, chkpt1 = pretrained_model_name_or_path_list[0:2]
         # chkpt2 = pretrained_model_name_or_path_list[2] if checkpoint_count == 3 else None

         # Validate that the checkpoints can be merged
         # Step 1: Load the model config and compare the checkpoints. We'll compare the model_index.json first while ignoring the keys starting with '_'
         _lowerCAmelCase    :					Union[str, Any]							=   []
         for pretrained_model_name_or_path in pretrained_model_name_or_path_list:
           _lowerCAmelCase    :					List[Any]							=   DiffusionPipeline.load_config(
               __lowerCAmelCase				,				cache_dir=__lowerCAmelCase				,				resume_download=__lowerCAmelCase				,				force_download=__lowerCAmelCase				,				proxies=__lowerCAmelCase				,				local_files_only=__lowerCAmelCase				,				use_auth_token=__lowerCAmelCase				,				revision=__lowerCAmelCase				,				)
           config_dicts.append(__lowerCAmelCase					)

         _lowerCAmelCase    :					List[Any]							=   True
         for idx in range(1				,				len(__lowerCAmelCase					)					):
           comparison_result &= self._compare_model_configs(config_dicts[idx - 1]				,				config_dicts[idx]					)
           if not force and comparison_result is False:
             raise ValueError("""Incompatible checkpoints. Please check model_index.json for the models."""					)
             print(config_dicts[0]				,				config_dicts[1]					)
         print("""Compatible model_index.json files found"""					)
         # Step 2: Basic Validation has succeeded. Let's download the models and save them into our local files.
         _lowerCAmelCase    :					Tuple							=   []
         for pretrained_model_name_or_path, config_dict in zip(__lowerCAmelCase				,				__lowerCAmelCase					):
           _lowerCAmelCase    :					Dict							=   [k for k in config_dict.keys() if not k.startswith("""_"""					)]
           _lowerCAmelCase    :					str							=   [os.path.join(__lowerCAmelCase				,				"""*"""					) for k in folder_names]
           allow_patterns += [
               WEIGHTS_NAME,
               SCHEDULER_CONFIG_NAME,
               CONFIG_NAME,
               ONNX_WEIGHTS_NAME,
               DiffusionPipeline.config_name,
           ]
           _lowerCAmelCase    :					List[Any]							=   config_dict.get("""_class_name"""					)
           _lowerCAmelCase    :					str							=   {"""diffusers""": __version__, """pipeline_class""": requested_pipeline_class}

           _lowerCAmelCase    :					Any							=   (
               pretrained_model_name_or_path
               if os.path.isdir(__lowerCAmelCase					)
               else snapshot_download(
                   __lowerCAmelCase				,				cache_dir=__lowerCAmelCase				,				resume_download=__lowerCAmelCase				,				proxies=__lowerCAmelCase				,				local_files_only=__lowerCAmelCase				,				use_auth_token=__lowerCAmelCase				,				revision=__lowerCAmelCase				,				allow_patterns=__lowerCAmelCase				,				user_agent=__lowerCAmelCase				,				)
           )
           print("""Cached Folder"""				,				__lowerCAmelCase					)
           cached_folders.append(__lowerCAmelCase					)

         # Step 3:-
         # Load the first checkpoint as a diffusion pipeline and modify its module state_dict in place
         _lowerCAmelCase    :					Optional[int]							=   DiffusionPipeline.from_pretrained(
             cached_folders[0]				,				torch_dtype=__lowerCAmelCase				,				device_map=__lowerCAmelCase					)
         final_pipe.to(self.device					)

         _lowerCAmelCase    :					Optional[int]							=   None
         if len(__lowerCAmelCase					) > 2:
           _lowerCAmelCase    :					int							=   os.path.join(cached_folders[2]					)

         if interp == "sigmoid":
           _lowerCAmelCase    :					str							=   CheckpointMergerPipeline.sigmoid
         elif interp == "inv_sigmoid":
           _lowerCAmelCase    :					Dict							=   CheckpointMergerPipeline.inv_sigmoid
         elif interp == "add_diff":
           _lowerCAmelCase    :					str							=   CheckpointMergerPipeline.add_difference
         else:
           _lowerCAmelCase    :					Tuple							=   CheckpointMergerPipeline.weighted_sum

         # Find each module's state dict.
         for attr in final_pipe.config.keys():
           if not attr.startswith("""_"""					):
             _lowerCAmelCase    :					Union[str, Any]							=   os.path.join(cached_folders[1]				,				__lowerCAmelCase					)
             if os.path.exists(__lowerCAmelCase					):
               _lowerCAmelCase    :					Any							=   [
                   *glob.glob(os.path.join(__lowerCAmelCase				,				"""*.safetensors"""					)					),
                   *glob.glob(os.path.join(__lowerCAmelCase				,				"""*.bin"""					)					),
               ]
               _lowerCAmelCase    :					Dict							=   files[0] if len(__lowerCAmelCase					) > 0 else None
             if len(__lowerCAmelCase					) < 3:
               _lowerCAmelCase    :					Optional[int]							=   None
             else:
               _lowerCAmelCase    :					Dict							=   os.path.join(cached_folders[2]				,				__lowerCAmelCase					)
               if os.path.exists(__lowerCAmelCase					):
                 _lowerCAmelCase    :					List[str]							=   [
                     *glob.glob(os.path.join(__lowerCAmelCase				,				"""*.safetensors"""					)					),
                     *glob.glob(os.path.join(__lowerCAmelCase				,				"""*.bin"""					)					),
                 ]
                 _lowerCAmelCase    :					Optional[Any]							=   files[0] if len(__lowerCAmelCase					) > 0 else None
                # For an attr if both checkpoint_path_1 and 2 are None, ignore.
                # If atleast one is present, deal with it according to interp method, of course only if the state_dict keys match.
             if checkpoint_path_a is None and checkpoint_path_a is None:
               print(f'Skipping {attr}: not present in 2nd or 3d model'					)
               continue
             try:
               _lowerCAmelCase    :					Union[str, Any]							=   getattr(__lowerCAmelCase				,				__lowerCAmelCase					)
               if isinstance(__lowerCAmelCase				,				__lowerCAmelCase					):  # ignore requires_safety_checker boolean
                 continue
               _lowerCAmelCase    :					Any							=   getattr(__lowerCAmelCase				,				"""state_dict"""					)
               _lowerCAmelCase    :					List[Any]							=   theta_a()

               _lowerCAmelCase    :					List[str]							=   getattr(__lowerCAmelCase				,				"""load_state_dict"""					)
               _lowerCAmelCase    :					Dict							=   (
                   safetensors.torch.load_file(__lowerCAmelCase					)
                   if (is_safetensors_available() and checkpoint_path_a.endswith(""".safetensors"""					))
                   else torch.load(__lowerCAmelCase				,				map_location="""cpu"""					)
               )
               _lowerCAmelCase    :					Union[str, Any]							=   None
               if checkpoint_path_a:
                 _lowerCAmelCase    :					Optional[int]							=   (
                     safetensors.torch.load_file(__lowerCAmelCase					)
                     if (is_safetensors_available() and checkpoint_path_a.endswith(""".safetensors"""					))
                     else torch.load(__lowerCAmelCase				,				map_location="""cpu"""					)
                 )

               if not theta_a.keys() == theta_a.keys():
                 print(f'Skipping {attr}: key mismatch'					)
                 continue
               if theta_a and not theta_a.keys() == theta_a.keys():
                 print(f'Skipping {attr}:y mismatch'					)
             except Exception as e:
               print(f'Skipping {attr} do to an unexpected error: {str(__lowerCAmelCase					)}'					)
               continue
             print(f'MERGING {attr}'					)

             for key in theta_a.keys():
               if theta_a:
                 _lowerCAmelCase    :					Any							=   theta_func(theta_a[key]				,				theta_a[key]				,				theta_a[key]				,				__lowerCAmelCase					)
               else:
                 _lowerCAmelCase    :					Optional[int]							=   theta_func(theta_a[key]				,				theta_a[key]				,				__lowerCAmelCase				,				__lowerCAmelCase					)

             del theta_a
             del theta_a
             update_theta_a(__lowerCAmelCase					)

             del theta_a
         return final_pipe




       @staticmethod
       def 							__UpperCamelCase    (       snake_case_				,				snake_case_				,				snake_case_				,				snake_case_					):
         return ((1 - alpha) * thetaa) + (alpha * thetaa)




       @staticmethod
       def 							__UpperCamelCase    (       snake_case_				,				snake_case_				,				snake_case_				,				snake_case_					):
         _lowerCAmelCase    :					Any							=   alpha * alpha * (3 - (2 * alpha))
         return thetaa + ((thetaa - thetaa) * alpha)




       @staticmethod
       def 							__UpperCamelCase    (       snake_case_				,				snake_case_				,				snake_case_				,				snake_case_					):
         import math

         _lowerCAmelCase    :					Union[str, Any]							=   0.5 - math.sin(math.asin(1.0 - 2.0 * alpha					) / 3.0					)
         return thetaa + ((thetaa - thetaa) * alpha)







       @staticmethod
       def 							__UpperCamelCase    (       snake_case_				,				snake_case_				,				snake_case_				,				snake_case_					):
         return thetaa + (thetaa - thetaa) * (1.0 - alpha)




'''simple docstring'''

def 		_UpperCAmelCase			(					_lowerCamelCase  :    int = 1_00						)      ->  int:
  _lowerCAmelCase    :					Dict							=   [[0 for _ in range(_lowerCamelCase						)] for _ in range(m + 1						)]
  for i in range(m + 1						):
    _lowerCAmelCase    :					List[str]							=   1

  for n in range(m + 1						):
    for k in range(1					, _lowerCamelCase						):
      memo[n][k] += memo[n][k - 1]
      if n > k:
        memo[n][k] += memo[n - k - 1][k]

  return memo[m][m - 1] - 1


if __name__ == "__main__":
     print(solution(int(input("""Enter a number: """).strip())))


