
"""simple docstring"""



import argparse
import logging
import os
from pathlib import Path
from typing import Any, Dict

import pytorch_lightning as pl
from pytorch_lightning.utilities import rank_zero_info

from transformers import (
    AdamW,
    AutoConfig,
    AutoModel,
    AutoModelForPreTraining,
    AutoModelForQuestionAnswering,
    AutoModelForSeqaSeqLM,
    AutoModelForSequenceClassification,
    AutoModelForTokenClassification,
    AutoModelWithLMHead,
    AutoTokenizer,
    PretrainedConfig,
    PreTrainedTokenizer,
)
from transformers.optimization import (
    Adafactor,
    get_cosine_schedule_with_warmup,
    get_cosine_with_hard_restarts_schedule_with_warmup,
    get_linear_schedule_with_warmup,
    get_polynomial_decay_schedule_with_warmup,
)
from transformers.utils.versions import require_version


a       :						Tuple       		=		logging.getLogger(__name__)

require_version('''pytorch_lightning>=1.0.4''')

a       :						Tuple       		=		{
    '''base''': AutoModel,
    '''sequence-classification''': AutoModelForSequenceClassification,
    '''question-answering''': AutoModelForQuestionAnswering,
    '''pretraining''': AutoModelForPreTraining,
    '''token-classification''': AutoModelForTokenClassification,
    '''language-modeling''': AutoModelWithLMHead,
    '''summarization''': AutoModelForSeqaSeqLM,
    '''translation''': AutoModelForSeqaSeqLM,
}


# update this and the import above to support new schedulers from transformers.optimization
a       :						Union[str, Any]       		=		{
    '''linear''': get_linear_schedule_with_warmup,
    '''cosine''': get_cosine_schedule_with_warmup,
    '''cosine_w_restarts''': get_cosine_with_hard_restarts_schedule_with_warmup,
    '''polynomial''': get_polynomial_decay_schedule_with_warmup,
    # '': get_constant_schedule,             # not supported for now
    # '': get_constant_schedule_with_warmup, # not supported for now
}
a       :						Optional[Any]       		=		sorted(arg_to_scheduler.keys())
a       :						Optional[Any]       		=		'''{''' + ''', '''.join(arg_to_scheduler_choices) + '''}'''




class 		a_    (			pl.LightningModule						):







    def __init__(      self      :							Union[str, Any]  ,       __UpperCamelCase      :							argparse.Namespace  ,       __UpperCamelCase      :							Optional[int]=None  ,       __UpperCamelCase      :							Dict="base"  ,       __UpperCamelCase      :							Optional[int]=None  ,       __UpperCamelCase      :							Any=None  ,       __UpperCamelCase      :							Optional[Any]=None  ,       **__UpperCamelCase      :							List[str]  ,       )		->Any:






        '''simple docstring'''






        super().__init__()
        # TODO: move to self.save_hyperparameters()
        # self.save_hyperparameters()
        # can also expand arguments into trainer signature for easier reading

        self.save_hyperparameters(__UpperCamelCase  )
        _UpperCAmelCase        = 0
        _UpperCAmelCase        = Path(self.hparams.output_dir  )
        _UpperCAmelCase        = self.hparams.cache_dir if self.hparams.cache_dir else None
        if config is None:
            _UpperCAmelCase        = AutoConfig.from_pretrained(
                self.hparams.config_name if self.hparams.config_name else self.hparams.model_name_or_path  ,       **({"""num_labels""": num_labels} if num_labels is not None else {})  ,       cache_dir=__UpperCamelCase  ,       **__UpperCamelCase  ,       )
        else:
            _UpperCAmelCase        = config

        _UpperCAmelCase        = ("""encoder_layerdrop""", """decoder_layerdrop""", """dropout""", """attention_dropout""")
        for p in extra_model_params:
            if getattr(self.hparams  ,       __UpperCamelCase  ,       __UpperCamelCase  ):
                assert hasattr(self.config  ,       __UpperCamelCase  ), f"""model config doesn't have a `{p}` attribute"""
                setattr(self.config  ,       __UpperCamelCase  ,       getattr(self.hparams  ,       __UpperCamelCase  )  )

        if tokenizer is None:
            _UpperCAmelCase        = AutoTokenizer.from_pretrained(
                self.hparams.tokenizer_name if self.hparams.tokenizer_name else self.hparams.model_name_or_path  ,       cache_dir=__UpperCamelCase  ,       )
        else:
            _UpperCAmelCase        = tokenizer
        _UpperCAmelCase        = MODEL_MODES[mode]
        if model is None:
            _UpperCAmelCase        = self.model_type.from_pretrained(
                self.hparams.model_name_or_path  ,       from_tf=bool(""".ckpt""" in self.hparams.model_name_or_path  )  ,       config=self.config  ,       cache_dir=__UpperCamelCase  ,       )
        else:
            _UpperCAmelCase        = model







    def   _snake_case       (      self      :							List[Any]  ,       *__UpperCamelCase      :							Tuple  ,       **__UpperCamelCase      :							Dict  )		->Optional[Any]:






        '''simple docstring'''






        _UpperCAmelCase        = self.model_type.from_pretrained(*__UpperCamelCase  ,       **__UpperCamelCase  )







    def   _snake_case       (      self      :							Optional[int]  )		->List[str]:






        '''simple docstring'''






        _UpperCAmelCase        = arg_to_scheduler[self.hparams.lr_scheduler]
        _UpperCAmelCase        = get_schedule_func(
            self.opt  ,       num_warmup_steps=self.hparams.warmup_steps  ,       num_training_steps=self.total_steps()  )
        _UpperCAmelCase        = {"""scheduler""": scheduler, """interval""": """step""", """frequency""": 1}
        return scheduler







    def   _snake_case       (      self      :							Optional[int]  )		->List[Any]:






        '''simple docstring'''






        _UpperCAmelCase        = self.model
        _UpperCAmelCase        = ["""bias""", """LayerNorm.weight"""]
        _UpperCAmelCase        = [
            {
                """params""": [
                    p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay  )
                ],  # check this named paramters
                """weight_decay""": self.hparams.weight_decay,
            },
            {
                """params""": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay  )],
                """weight_decay""": 0.0,
            },
        ]
        if self.hparams.adafactor:
            _UpperCAmelCase        = Adafactor(
                __UpperCamelCase  ,       lr=self.hparams.learning_rate  ,       scale_parameter=__UpperCamelCase  ,       relative_step=__UpperCamelCase  )

        else:
            _UpperCAmelCase        = AdamW(
                __UpperCamelCase  ,       lr=self.hparams.learning_rate  ,       eps=self.hparams.adam_epsilon  )
        _UpperCAmelCase        = optimizer

        _UpperCAmelCase        = self.get_lr_scheduler()

        return [optimizer], [scheduler]







    def   _snake_case       (      self      :							Optional[Any]  ,       __UpperCamelCase      :							Union[str, Any]  ,       __UpperCamelCase      :							Union[str, Any]  )		->Any:






        '''simple docstring'''






        return self.validation_step(__UpperCamelCase  ,       __UpperCamelCase  )







    def   _snake_case       (      self      :							Any  ,       __UpperCamelCase      :							Any  )		->Optional[Any]:






        '''simple docstring'''






        return self.validation_end(__UpperCamelCase  )







    def   _snake_case       (      self      :							Dict  )		->int:






        '''simple docstring'''






        _UpperCAmelCase        = max(1  ,       self.hparams.gpus  )  # TODO: consider num_tpu_cores
        _UpperCAmelCase        = self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
        return (self.dataset_size / effective_batch_size) * self.hparams.max_epochs







    def   _snake_case       (      self      :							str  ,       __UpperCamelCase      :							Dict  )		->List[Any]:






        '''simple docstring'''






        if stage == "test":
            _UpperCAmelCase        = len(self.test_dataloader().dataset  )
        else:
            _UpperCAmelCase        = self.get_dataloader("""train"""  ,       self.hparams.train_batch_size  ,       shuffle=__UpperCamelCase  )
            _UpperCAmelCase        = len(self.train_dataloader().dataset  )







    def   _snake_case       (      self      :							Dict  ,       __UpperCamelCase      :							str  ,       __UpperCamelCase      :							int  ,       __UpperCamelCase      :							bool = False  )		->Any:






        '''simple docstring'''






        raise NotImplementedError("""You must implement this for your task"""  )







    def   _snake_case       (      self      :							List[str]  )		->List[str]:






        '''simple docstring'''






        return self.train_loader







    def   _snake_case       (      self      :							Any  )		->Union[str, Any]:






        '''simple docstring'''






        return self.get_dataloader("""dev"""  ,       self.hparams.eval_batch_size  ,       shuffle=__UpperCamelCase  )







    def   _snake_case       (      self      :							str  )		->Optional[Any]:






        '''simple docstring'''






        return self.get_dataloader("""test"""  ,       self.hparams.eval_batch_size  ,       shuffle=__UpperCamelCase  )







    def   _snake_case       (      self      :							List[str]  ,       __UpperCamelCase      :							int  )		->Tuple:






        '''simple docstring'''






        return os.path.join(
            self.hparams.data_dir  ,       """cached_{}_{}_{}""".format(
                __UpperCamelCase  ,       list(filter(__UpperCamelCase  ,       self.hparams.model_name_or_path.split("""/"""  )  )  ).pop()  ,       str(self.hparams.max_seq_length  )  ,       )  ,       )







    @pl.utilities.rank_zero_only
    def   _snake_case       (      self      :							Union[str, Any]  ,       __UpperCamelCase      :							Dict[str, Any]  )		->None:






        '''simple docstring'''






        _UpperCAmelCase        = self.output_dir.joinpath("""best_tfmr"""  )
        _UpperCAmelCase        = self.step_count
        self.model.save_pretrained(__UpperCamelCase  )
        self.tokenizer.save_pretrained(__UpperCamelCase  )







    @staticmethod
    def   _snake_case       (      __UpperCamelCase      :							Tuple  ,       __UpperCamelCase      :							List[Any]  )		->List[str]:






        '''simple docstring'''






        parser.add_argument(
            """--model_name_or_path"""  ,       default=__UpperCamelCase  ,       type=__UpperCamelCase  ,       required=__UpperCamelCase  ,       help="""Path to pretrained model or model identifier from huggingface.co/models"""  ,       )
        parser.add_argument(
            """--config_name"""  ,       default=""""""  ,       type=__UpperCamelCase  ,       help="""Pretrained config name or path if not the same as model_name"""  )
        parser.add_argument(
            """--tokenizer_name"""  ,       default=__UpperCamelCase  ,       type=__UpperCamelCase  ,       help="""Pretrained tokenizer name or path if not the same as model_name"""  ,       )
        parser.add_argument(
            """--cache_dir"""  ,       default=str(Path(__UpperCamelCase  ).parent / """test_run""" / """cache"""  )  ,       type=__UpperCamelCase  ,       help="""Where do you want to store the pre-trained models downloaded from huggingface.co"""  ,       )
        parser.add_argument(
            """--encoder_layerdrop"""  ,       type=__UpperCamelCase  ,       help="""Encoder layer dropout probability (Optional). Goes into model.config"""  ,       )
        parser.add_argument(
            """--decoder_layerdrop"""  ,       type=__UpperCamelCase  ,       help="""Decoder layer dropout probability (Optional). Goes into model.config"""  ,       )
        parser.add_argument(
            """--dropout"""  ,       type=__UpperCamelCase  ,       help="""Dropout probability (Optional). Goes into model.config"""  ,       )
        parser.add_argument(
            """--attention_dropout"""  ,       type=__UpperCamelCase  ,       help="""Attention dropout probability (Optional). Goes into model.config"""  ,       )
        parser.add_argument("""--learning_rate"""  ,       default=5e-5  ,       type=__UpperCamelCase  ,       help="""The initial learning rate for Adam."""  )
        parser.add_argument(
            """--lr_scheduler"""  ,       default="""linear"""  ,       choices=__UpperCamelCase  ,       metavar=__UpperCamelCase  ,       type=__UpperCamelCase  ,       help="""Learning rate scheduler"""  ,       )
        parser.add_argument("""--weight_decay"""  ,       default=0.0  ,       type=__UpperCamelCase  ,       help="""Weight decay if we apply some."""  )
        parser.add_argument("""--adam_epsilon"""  ,       default=1e-8  ,       type=__UpperCamelCase  ,       help="""Epsilon for Adam optimizer."""  )
        parser.add_argument("""--warmup_steps"""  ,       default=0  ,       type=__UpperCamelCase  ,       help="""Linear warmup over warmup_steps."""  )
        parser.add_argument("""--num_workers"""  ,       default=4  ,       type=__UpperCamelCase  ,       help="""kwarg passed to DataLoader"""  )
        parser.add_argument("""--num_train_epochs"""  ,       dest="""max_epochs"""  ,       default=3  ,       type=__UpperCamelCase  )
        parser.add_argument("""--train_batch_size"""  ,       default=32  ,       type=__UpperCamelCase  )
        parser.add_argument("""--eval_batch_size"""  ,       default=32  ,       type=__UpperCamelCase  )
        parser.add_argument("""--adafactor"""  ,       action="""store_true"""  )







class 		a_    (			pl.Callback						):







    def   _snake_case       (      self      :							int  ,       __UpperCamelCase      :							str  ,       __UpperCamelCase      :							Tuple  )		->List[Any]:






        '''simple docstring'''






        if (
            trainer.is_global_zero and trainer.global_rank == 0
        ):  # we initialize the retriever only on master worker with RAY. In new pytorch-lightning accelorators are removed.
            pl_module.model.rag.retriever.init_retrieval()  # better to use hook functions.







class 		a_    (			pl.Callback						):







    def   _snake_case       (      self      :							Dict  ,       __UpperCamelCase      :							str  ,       __UpperCamelCase      :							Optional[int]  )		->List[str]:






        '''simple docstring'''






        for name, param in pl_module.model.rag.named_parameters():
            if param.grad is None:
                print(__UpperCamelCase  )







class 		a_    (			pl.Callback						):







    def   _snake_case       (      self      :							Any  ,       __UpperCamelCase      :							Union[str, Any]  ,       __UpperCamelCase      :							List[Any]  )		->Tuple:






        '''simple docstring'''






        _UpperCAmelCase        = trainer.lr_schedulers[0]["""scheduler"""]
        _UpperCAmelCase        = {f"""lr_group_{i}""": lr for i, lr in enumerate(lr_scheduler.get_lr()  )}
        pl_module.logger.log_metrics(__UpperCamelCase  )







    def   _snake_case       (      self      :							Any  ,       __UpperCamelCase      :							pl.Trainer  ,       __UpperCamelCase      :							pl.LightningModule  )		->Any:






        '''simple docstring'''






        rank_zero_info("""***** Validation results *****"""  )
        _UpperCAmelCase        = trainer.callback_metrics
        # Log results
        for key in sorted(__UpperCamelCase  ):
            if key not in ["log", "progress_bar"]:
                rank_zero_info("""{} = {}\n""".format(__UpperCamelCase  ,       str(metrics[key]  )  )  )







    def   _snake_case       (      self      :							List[Any]  ,       __UpperCamelCase      :							pl.Trainer  ,       __UpperCamelCase      :							pl.LightningModule  )		->Optional[int]:






        '''simple docstring'''






        rank_zero_info("""***** Test results *****"""  )
        _UpperCAmelCase        = trainer.callback_metrics
        # Log and save results to file
        _UpperCAmelCase        = os.path.join(pl_module.hparams.output_dir  ,       """test_results.txt"""  )
        with open(__UpperCamelCase  ,       """w"""  ) as writer:
            for key in sorted(__UpperCamelCase  ):
                if key not in ["log", "progress_bar"]:
                    rank_zero_info("""{} = {}\n""".format(__UpperCamelCase  ,       str(metrics[key]  )  )  )
                    writer.write("""{} = {}\n""".format(__UpperCamelCase  ,       str(metrics[key]  )  )  )







def 			_UpperCamelCase						(    _A       ,   _A   )     ->	None:





    """simple docstring"""

    parser.add_argument(
        """--output_dir"""       ,   default=str(Path(_A   ).parent / """test_run""" / """model_checkpoints"""   )       ,   type=_A       ,   help="""The output directory where the model predictions and checkpoints will be written."""       ,   )
    parser.add_argument(
        """--fp16"""       ,   action="""store_true"""       ,   help="""Whether to use 16-bit (mixed) precision (through NVIDIA apex) instead of 32-bit"""       ,   )

    parser.add_argument(
        """--fp16_opt_level"""       ,   type=_A       ,   default="""O2"""       ,   help=(
            """For fp16: Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']."""
            """See details at https://nvidia.github.io/apex/amp.html"""
        )       ,   )
    parser.add_argument("""--n_tpu_cores"""       ,   dest="""tpu_cores"""       ,   type=_A   )
    parser.add_argument("""--max_grad_norm"""       ,   dest="""gradient_clip_val"""       ,   default=1.0       ,   type=_A       ,   help="""Max gradient norm"""   )
    parser.add_argument("""--do_train"""       ,   action="""store_true"""       ,   help="""Whether to run training."""   )
    parser.add_argument("""--do_predict"""       ,   action="""store_true"""       ,   help="""Whether to run predictions on the test set."""   )
    parser.add_argument(
        """--gradient_accumulation_steps"""       ,   dest="""accumulate_grad_batches"""       ,   type=_A       ,   default=1       ,   help="""Number of updates steps to accumulate before performing a backward/update pass."""       ,   )
    parser.add_argument("""--seed"""       ,   type=_A       ,   default=4_2       ,   help="""random seed for initialization"""   )
    parser.add_argument(
        """--data_dir"""       ,   default=str(Path(_A   ).parent / """test_run""" / """dummy-train-data"""   )       ,   type=_A       ,   help="""The input data dir. Should contain the training files for the CoNLL-2003 NER task."""       ,   )







def 			_UpperCamelCase						(    _A       ,   _A       ,   _A=None       ,   _A=True       ,   _A=[]       ,   _A=None       ,   _A=None       ,   **_A       ,   )     ->	Any:





    """simple docstring"""

    pl.seed_everything(args.seed   )

    # init model
    _UpperCAmelCase        = Path(model.hparams.output_dir   )
    odir.mkdir(exist_ok=_A   )

    # add custom checkpoints
    if checkpoint_callback is None:
        _UpperCAmelCase        = pl.callbacks.ModelCheckpoint(
            filepath=args.output_dir       ,   prefix="""checkpoint"""       ,   monitor="""val_loss"""       ,   mode="""min"""       ,   save_top_k=1   )
    if early_stopping_callback:
        extra_callbacks.append(_A   )
    if logging_callback is None:
        _UpperCAmelCase        = LoggingCallback()

    _UpperCAmelCase        = {}

    if args.fpaa:
        _UpperCAmelCase        = 1_6

    if args.gpus > 1:
        _UpperCAmelCase        = """auto"""
        _UpperCAmelCase        = """ddp"""

    _UpperCAmelCase        = args.accumulate_grad_batches
    _UpperCAmelCase        = None
    _UpperCAmelCase        = """auto"""

    _UpperCAmelCase        = pl.Trainer.from_argparse_args(
        _A       ,   weights_summary=_A       ,   callbacks=[logging_callback] + extra_callbacks + [InitCallback()] + [checkpoint_callback]       ,   logger=_A       ,   val_check_interval=1       ,   num_sanity_val_steps=2       ,   **_A       ,   )

    if args.do_train:
        trainer.fit(_A   )

    else:
        print("""RAG modeling tests with new set functions successfuly executed!"""   )
    return trainer

"""simple docstring"""



def 			_UpperCamelCase						(    _A = 1_0_0_0   )     ->	int:





    """simple docstring"""

    _UpperCAmelCase     ,_UpperCAmelCase        = 1, 1
    _UpperCAmelCase        = 2
    while True:
        _UpperCAmelCase        = 0
        _UpperCAmelCase        = fa + fa
        _UpperCAmelCase     ,_UpperCAmelCase        = fa, f
        index += 1
        for _ in str(_A   ):
            i += 1
        if i == n:
            break
    return index


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