



import re
from typing import Callable, List, Optional, Union

import tensorflow as tf


try:
      from tensorflow.keras.optimizers.legacy import Adam
except ImportError:
      from tensorflow.keras.optimizers import Adam

class       _SCREAMING_SNAKE_CASE	(tf.keras.optimizers.schedules.LearningRateSchedule ):





     def __init__(       self :							Union[str, Any]     ,  UpperCamelCase :							float     ,  UpperCamelCase :							Callable     ,  UpperCamelCase :							int     ,  UpperCamelCase :							float = 1.0     ,  UpperCamelCase :							str = None     ,  )->Optional[int]:
      super().__init__()
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	initial_learning_rate
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	warmup_steps
      __SCREAMING_SNAKE_CASE       :    Optional[int]       =	power
      __SCREAMING_SNAKE_CASE       :    List[Any]       =	decay_schedule_fn
      __SCREAMING_SNAKE_CASE       :    int       =	name





     def __call__(       self :							List[Any]     ,  UpperCamelCase :							Any				)->Optional[int]:
      with tf.name_scope(self.name or "WarmUp"				) as name:
       # Implements polynomial warmup. i.e., if global_step < warmup_steps, the
       # learning rate will be `global_step/num_warmup_steps * init_lr`.
       __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	tf.cast(UpperCamelCase     ,  tf.floataa				)
       __SCREAMING_SNAKE_CASE       :    Optional[int]       =	tf.cast(self.warmup_steps     ,  tf.floataa				)
       __SCREAMING_SNAKE_CASE       :    Any       =	global_step_float / warmup_steps_float
       __SCREAMING_SNAKE_CASE       :    Tuple       =	self.initial_learning_rate * tf.math.pow(UpperCamelCase     ,  self.power				)
       return tf.cond(
           global_step_float < warmup_steps_float     ,  lambda: warmup_learning_rate     ,  lambda: self.decay_schedule_fn(step - self.warmup_steps				)     ,  name=UpperCamelCase     ,  )






     def 	__snake_case    (       self :							str				)->List[str]:
      return {
          "initial_learning_rate": self.initial_learning_rate,
          "decay_schedule_fn": self.decay_schedule_fn,
          "warmup_steps": self.warmup_steps,
          "power": self.power,
          "name": self.name,
      }






def 	_lowerCAmelCase						(				__lowerCamelCase   :     float		,	__lowerCamelCase   :     int		,	__lowerCamelCase   :     int		,	__lowerCamelCase   :     float = 0.0		,	__lowerCamelCase   :     float = 0.9		,	__lowerCamelCase   :     float = 0.999		,	__lowerCamelCase   :     float = 1E-8		,	__lowerCamelCase   :     Optional[float] = None		,	__lowerCamelCase   :     Optional[float] = None		,	__lowerCamelCase   :     float = 0.0		,	__lowerCamelCase   :     float = 1.0		,	__lowerCamelCase   :     Optional[List[str]] = None		,	):



 """simple docstring"""





 __SCREAMING_SNAKE_CASE       :    Tuple       =	tf.keras.optimizers.schedules.PolynomialDecay(
     initial_learning_rate=__lowerCamelCase		,	decay_steps=num_train_steps - num_warmup_steps		,	end_learning_rate=init_lr * min_lr_ratio		,	power=__lowerCamelCase		,	)
 if num_warmup_steps:
  __SCREAMING_SNAKE_CASE       :    List[str]       =	WarmUp(
      initial_learning_rate=__lowerCamelCase		,	decay_schedule_fn=__lowerCamelCase		,	warmup_steps=__lowerCamelCase		,	)
 if weight_decay_rate > 0.0:
  __SCREAMING_SNAKE_CASE       :    int       =	AdamWeightDecay(
      learning_rate=__lowerCamelCase		,	weight_decay_rate=__lowerCamelCase		,	beta_a=__lowerCamelCase		,	beta_a=__lowerCamelCase		,	epsilon=__lowerCamelCase		,	clipnorm=__lowerCamelCase		,	global_clipnorm=__lowerCamelCase		,	exclude_from_weight_decay=["LayerNorm", "layer_norm", "bias"]		,	include_in_weight_decay=__lowerCamelCase		,	)
 else:
  __SCREAMING_SNAKE_CASE       :    Any       =	tf.keras.optimizers.Adam(
      learning_rate=__lowerCamelCase		,	beta_a=__lowerCamelCase		,	beta_a=__lowerCamelCase		,	epsilon=__lowerCamelCase		,	clipnorm=__lowerCamelCase		,	global_clipnorm=__lowerCamelCase		,	)
 # We return the optimizer and the LR scheduler in order to better track the
 # evolution of the LR independently of the optimizer.
 return optimizer, lr_schedule

class       _SCREAMING_SNAKE_CASE	(UpperCamelCase ):





     def __init__(       self :							Optional[Any]     ,  UpperCamelCase :							Union[float, tf.keras.optimizers.schedules.LearningRateSchedule] = 0.0_0_1     ,  UpperCamelCase :							float = 0.9     ,  UpperCamelCase :							float = 0.9_9_9     ,  UpperCamelCase :							float = 1E-7     ,  UpperCamelCase :							bool = False     ,  UpperCamelCase :							float = 0.0     ,  UpperCamelCase :							Optional[List[str]] = None     ,  UpperCamelCase :							Optional[List[str]] = None     ,  UpperCamelCase :							str = "AdamWeightDecay"     ,  **UpperCamelCase :							int     ,  )->List[Any]:
      super().__init__(UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase     ,  **UpperCamelCase				)
      __SCREAMING_SNAKE_CASE       :    Union[str, Any]       =	weight_decay_rate
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	include_in_weight_decay
      __SCREAMING_SNAKE_CASE       :    Any       =	exclude_from_weight_decay





     @classmethod
     def 	__snake_case    (       cls :							Any     ,  UpperCamelCase :							Optional[int]				)->List[Any]:
      __SCREAMING_SNAKE_CASE       :    List[str]       =	{"WarmUp": WarmUp}
      return super(UpperCamelCase     ,  cls				).from_config(UpperCamelCase     ,  custom_objects=UpperCamelCase				)





     def 	__snake_case    (       self :							Any     ,  UpperCamelCase :							Optional[Any]     ,  UpperCamelCase :							Dict     ,  UpperCamelCase :							int				)->int:
      super(UpperCamelCase     ,  self				)._prepare_local(UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase				)
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	tf.constant(
          self.weight_decay_rate     ,  name="adam_weight_decay_rate"				)





     def 	__snake_case    (       self :							Optional[int]     ,  UpperCamelCase :							Optional[int]     ,  UpperCamelCase :							List[str]     ,  UpperCamelCase :							Tuple				)->Any:
      __SCREAMING_SNAKE_CASE       :    List[str]       =	self._do_use_weight_decay(var.name				)
      if do_decay:
       return var.assign_sub(
           learning_rate * var * apply_state[(var.device, var.dtype.base_dtype)]["weight_decay_rate"]     ,  use_locking=self._use_locking     ,  )
      return tf.no_op()





     def 	__snake_case    (       self :							str     ,  UpperCamelCase :							List[Any]     ,  UpperCamelCase :							Optional[int]=None     ,  **UpperCamelCase :							str				)->List[Any]:
      __SCREAMING_SNAKE_CASE,		__SCREAMING_SNAKE_CASE       :    int       =	list(zip(*UpperCamelCase				)				)
      return super(UpperCamelCase     ,  self				).apply_gradients(zip(UpperCamelCase     ,  UpperCamelCase				)     ,  name=UpperCamelCase     ,  **UpperCamelCase				)





     def 	__snake_case    (       self :							Dict     ,  UpperCamelCase :							Union[str, Any]     ,  UpperCamelCase :							Optional[int]     ,  UpperCamelCase :							Any				)->Optional[Any]:
      if apply_state is None:
       return self._decayed_lr_t[var_dtype], {}

      __SCREAMING_SNAKE_CASE       :    Any       =	apply_state or {}
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	apply_state.get((var_device, var_dtype)				)
      if coefficients is None:
       __SCREAMING_SNAKE_CASE       :    Any       =	self._fallback_apply_state(UpperCamelCase     ,  UpperCamelCase				)
       __SCREAMING_SNAKE_CASE       :    List[str]       =	coefficients

      return coefficients["lr_t"], {"apply_state": apply_state}





     def 	__snake_case    (       self :							str     ,  UpperCamelCase :							Tuple     ,  UpperCamelCase :							List[str]     ,  UpperCamelCase :							int=None				)->List[Any]:
      __SCREAMING_SNAKE_CASE,		__SCREAMING_SNAKE_CASE       :    str       =	self._get_lr(var.device     ,  var.dtype.base_dtype     ,  UpperCamelCase				)
      __SCREAMING_SNAKE_CASE       :    str       =	self._decay_weights_op(UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase				)
      with tf.control_dependencies([decay]				):
       return super(UpperCamelCase     ,  self				)._resource_apply_dense(UpperCamelCase     ,  UpperCamelCase     ,  **UpperCamelCase				)





     def 	__snake_case    (       self :							Dict     ,  UpperCamelCase :							Optional[Any]     ,  UpperCamelCase :							Optional[int]     ,  UpperCamelCase :							Union[str, Any]     ,  UpperCamelCase :							List[str]=None				)->List[Any]:
      __SCREAMING_SNAKE_CASE,		__SCREAMING_SNAKE_CASE       :    Any       =	self._get_lr(var.device     ,  var.dtype.base_dtype     ,  UpperCamelCase				)
      __SCREAMING_SNAKE_CASE       :    List[str]       =	self._decay_weights_op(UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase				)
      with tf.control_dependencies([decay]				):
       return super(UpperCamelCase     ,  self				)._resource_apply_sparse(UpperCamelCase     ,  UpperCamelCase     ,  UpperCamelCase     ,  **UpperCamelCase				)





     def 	__snake_case    (       self :							Tuple				)->Any:
      __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	super().get_config()
      config.update({"weight_decay_rate": self.weight_decay_rate}				)
      return config






     def 	__snake_case    (       self :							Dict     ,  UpperCamelCase :							Optional[Any]				)->Tuple:
      if self.weight_decay_rate == 0:
       return False

      if self._include_in_weight_decay:
       for r in self._include_in_weight_decay:
        if re.search(UpperCamelCase     ,  UpperCamelCase				) is not None:
         return True

      if self._exclude_from_weight_decay:
       for r in self._exclude_from_weight_decay:
        if re.search(UpperCamelCase     ,  UpperCamelCase				) is not None:
         return False
      return True






class       _SCREAMING_SNAKE_CASE	(UpperCamelCase ):





     def __init__(       self :							List[Any]				)->Tuple:
      __SCREAMING_SNAKE_CASE       :    List[str]       =	[]
      __SCREAMING_SNAKE_CASE       :    Dict       =	None





     @property
     def 	__snake_case    (       self :							str				)->str:
      if self._accum_steps is None:
       __SCREAMING_SNAKE_CASE       :    Dict       =	tf.Variable(
           tf.constant(0     ,  dtype=tf.intaa				)     ,  trainable=UpperCamelCase     ,  synchronization=tf.VariableSynchronization.ON_READ     ,  aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA     ,  )

      return self._accum_steps.value()





     @property
     def 	__snake_case    (       self :							Any				)->int:
      if not self._gradients:
       raise ValueError("The accumulator should be called first to initialize the gradients"				)
      return [gradient.value() if gradient is not None else gradient for gradient in self._gradients]





     def __call__(       self :							str     ,  UpperCamelCase :							int				)->Optional[Any]:
      if not self._gradients:
       __SCREAMING_SNAKE_CASE       :    Optional[Any]       =	self.step  # Create the step variable.
       self._gradients.extend(
           [
               tf.Variable(
                   tf.zeros_like(UpperCamelCase				)     ,  trainable=UpperCamelCase     ,  synchronization=tf.VariableSynchronization.ON_READ     ,  aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA     ,  )
               if gradient is not None
               else gradient
               for gradient in gradients
           ]				)
      if len(UpperCamelCase				) != len(self._gradients				):
       raise ValueError(F"""Expected {len(self._gradients				)} gradients, but got {len(UpperCamelCase				)}"""				)

      for accum_gradient, gradient in zip(self._gradients     ,  UpperCamelCase				):
       if accum_gradient is not None and gradient is not None:
        accum_gradient.assign_add(UpperCamelCase				)

      self._accum_steps.assign_add(1				)






     def 	__snake_case    (       self :							Any				)->Any:
      if not self._gradients:
       return
      self._accum_steps.assign(0				)
      for gradient in self._gradients:
       if gradient is not None:
        gradient.assign(tf.zeros_like(UpperCamelCase				)				)











from math import sqrt






def 	_lowerCAmelCase						(				__lowerCamelCase   :     int = 1000000     ):



 """simple docstring"""





 __SCREAMING_SNAKE_CASE       :    int       =	0
 __SCREAMING_SNAKE_CASE       :    int       =	0
 __SCREAMING_SNAKE_CASE       :    int

 while num_cuboids <= limit:
  max_cuboid_size += 1
  for sum_shortest_sides in range(2		,	2 * max_cuboid_size + 1     ):
   if sqrt(sum_shortest_sides**2 + max_cuboid_size**2     ).is_integer():
    num_cuboids += (
        min(__lowerCamelCase		,	sum_shortest_sides // 2     )
        - max(1		,	sum_shortest_sides - max_cuboid_size     )
        + 1
    )

 return max_cuboid_size


if __name__ == "__main__":
      print(f'''{solution() = }''')






