


# DISCLAIMER: This code is strongly influenced by https://github.com/pesser/pytorch_diffusion
# and https://github.com/hojonathanho/diffusion

from dataclasses import dataclass
from typing import Optional, Tuple, Union

import flax
import jax.numpy as jnp

from ..configuration_utils import ConfigMixin, register_to_config
from .scheduling_utils_flax import (
    CommonSchedulerState,
    FlaxKarrasDiffusionSchedulers,
    FlaxSchedulerMixin,
    FlaxSchedulerOutput,
    add_noise_common,
    get_velocity_common,
)







@flax.struct.dataclass
class lowerCAmelCase_		:

 '''simple docstring'''

 __snake_case				=    42
 __snake_case				=    42

 # setable values
 __snake_case				=    42
 __snake_case				=    42
 __snake_case				=    None



 @classmethod
 def 		UpperCamelCase__	(      cls						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, ):
       return cls(
           common=_UpperCAmelCase						, final_alpha_cumprod=_UpperCAmelCase						, init_noise_sigma=_UpperCAmelCase						, timesteps=_UpperCAmelCase						, )







@dataclass
class lowerCAmelCase_		(					lowerCamelCase__			):

 '''simple docstring'''

 __snake_case				=    42







class lowerCAmelCase_		(					lowerCamelCase__   ,		lowerCamelCase__			):

 '''simple docstring'''

 __snake_case				=    [e.name for e in FlaxKarrasDiffusionSchedulers]

 __snake_case				=    42



 @property
 def 		UpperCamelCase__	(      self   ):
       return True



 @register_to_config
 def __init__(      self						, _UpperCAmelCase = 10_00						, _UpperCAmelCase = 0.0_001						, _UpperCAmelCase = 0.02						, _UpperCAmelCase = "linear"						, _UpperCAmelCase = None						, _UpperCAmelCase = True						, _UpperCAmelCase = 0						, _UpperCAmelCase = "epsilon"						, _UpperCAmelCase = jnp.floataa						, ):
       snake_case_			= dtype



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase = None   ):
       if common is None:
             snake_case_			= CommonSchedulerState.create(self   )

       # At every step in ddim, we are looking into the previous alphas_cumprod
       # For the final step, there is no previous alphas_cumprod because we are already at 0
       # `set_alpha_to_one` decides whether we set this parameter simply to one or
       # whether we use the final alpha of the "non-previous" one.
       snake_case_			= (
           jnp.array(1.0						, dtype=self.dtype   ) if self.config.set_alpha_to_one else common.alphas_cumprod[0]
       )

       # standard deviation of the initial noise distribution
       snake_case_			= jnp.array(1.0						, dtype=self.dtype   )

       snake_case_			= jnp.arange(0						, self.config.num_train_timesteps   ).round()[::-1]

       return DDIMSchedulerState.create(
           common=_UpperCAmelCase						, final_alpha_cumprod=_UpperCAmelCase						, init_noise_sigma=_UpperCAmelCase						, timesteps=_UpperCAmelCase						, )



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase = None   ):
       return sample



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase = ()   ):
       snake_case_			= self.config.num_train_timesteps // num_inference_steps
       # creates integer timesteps by multiplying by ratio
       # rounding to avoid issues when num_inference_step is power of 3
       snake_case_			= (jnp.arange(0						, _UpperCAmelCase   ) * step_ratio).round()[::-1] + self.config.steps_offset

       return state.replace(
           num_inference_steps=_UpperCAmelCase						, timesteps=_UpperCAmelCase						, )



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase   ):
       snake_case_			= state.common.alphas_cumprod[timestep]
       snake_case_			= jnp.where(
           prev_timestep >= 0						, state.common.alphas_cumprod[prev_timestep]						, state.final_alpha_cumprod   )
       snake_case_			= 1 - alpha_prod_t
       snake_case_			= 1 - alpha_prod_t_prev

       snake_case_			= (beta_prod_t_prev / beta_prod_t) * (1 - alpha_prod_t / alpha_prod_t_prev)

       return variance



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase = 0.0						, _UpperCAmelCase = True						, ):
       if state.num_inference_steps is None:
             raise ValueError(
                 '''Number of inference steps is \'None\', you need to run \'set_timesteps\' after creating the scheduler'''   )

       # See formulas (12) and (16) of DDIM paper https://arxiv.org/pdf/2010.02502.pdf
       # Ideally, read DDIM paper in-detail understanding

       # Notation (<variable name> -> <name in paper>
       # - pred_noise_t -> e_theta(x_t, t)
       # - pred_original_sample -> f_theta(x_t, t) or x_0
       # - std_dev_t -> sigma_t
       # - eta -> η
       # - pred_sample_direction -> "direction pointing to x_t"
       # - pred_prev_sample -> "x_t-1"

       # 1. get previous step value (=t-1)
       snake_case_			= timestep - self.config.num_train_timesteps // state.num_inference_steps

       snake_case_			= state.common.alphas_cumprod
       snake_case_			= state.final_alpha_cumprod

       # 2. compute alphas, betas
       snake_case_			= alphas_cumprod[timestep]
       snake_case_			= jnp.where(prev_timestep >= 0						, alphas_cumprod[prev_timestep]						, _UpperCAmelCase   )

       snake_case_			= 1 - alpha_prod_t

       # 3. compute predicted original sample from predicted noise also called
       # "predicted x_0" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
       if self.config.prediction_type == "epsilon":
             snake_case_			= (sample - beta_prod_t ** 0.5 * model_output) / alpha_prod_t ** 0.5
             snake_case_			= model_output
       elif self.config.prediction_type == "sample":
             snake_case_			= model_output
             snake_case_			= (sample - alpha_prod_t ** 0.5 * pred_original_sample) / beta_prod_t ** 0.5
       elif self.config.prediction_type == "v_prediction":
             snake_case_			= (alpha_prod_t**0.5) * sample - (beta_prod_t**0.5) * model_output
             snake_case_			= (alpha_prod_t**0.5) * model_output + (beta_prod_t**0.5) * sample
       else:
             raise ValueError(
                 F'''prediction_type given as {self.config.prediction_type} must be one of `epsilon`, `sample`, or'''
                 ''' `v_prediction`'''   )

       # 4. compute variance: "sigma_t(η)" -> see formula (16)
       # σ_t = sqrt((1 − α_t−1)/(1 − α_t)) * sqrt(1 − α_t/α_t−1)
       snake_case_			= self._get_variance(_UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase   )
       snake_case_			= eta * variance ** 0.5

       # 5. compute "direction pointing to x_t" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
       snake_case_			= (1 - alpha_prod_t_prev - std_dev_t**2) ** 0.5 * pred_epsilon

       # 6. compute x_t without "random noise" of formula (12) from https://arxiv.org/pdf/2010.02502.pdf
       snake_case_			= alpha_prod_t_prev ** 0.5 * pred_original_sample + pred_sample_direction

       if not return_dict:
             return (prev_sample, state)

       return FlaxDDIMSchedulerOutput(prev_sample=_UpperCAmelCase						, state=_UpperCAmelCase   )



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, ):
       return add_noise_common(state.common						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase   )



 def 		UpperCamelCase__	(      self						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase						, ):
       return get_velocity_common(state.common						, _UpperCAmelCase						, _UpperCAmelCase						, _UpperCAmelCase   )





 def __len__(      self   ):
       return self.config.num_train_timesteps



def 			__lowerCAmelCase       (SCREAMING_SNAKE_CASE = 1000   )->    int:




      """simple docstring"""

      snake_case_			= [0, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8]
      # number of letters in twenty, thirty, ..., ninety (0 for numbers less than
      # 20 due to inconsistency in teens)
      snake_case_			= [0, 0, 6, 6, 5, 5, 5, 7, 6, 6]

      snake_case_			= 0

      for i in range(1   ,   n + 1   ):
            if i < 1000:
                  if i >= 100:
                        # add number of letters for "n hundred"
                        count += ones_counts[i // 100] + 7

                        if i % 100 != 0:
                              # add number of letters for "and" if number is not multiple
                              # of 100
                              count += 3

                  if 0 < i % 100 < 20:
                        # add number of letters for one, two, three, ..., nineteen
                        # (could be combined with below if not for inconsistency in
                        # teens)
                        count += ones_counts[i % 100]
                  else:
                        # add number of letters for twenty, twenty one, ..., ninety
                        # nine
                        count += ones_counts[i % 10]
                        count += tens_counts[(i % 100 - i % 10) // 10]
            else:
                  count += ones_counts[i // 1000] + 8
      return count


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