





# We ignore warnings about stepping the scheduler since we step it ourselves during gradient accumulation

import warnings

from .state import AcceleratorState, GradientState


warnings.filterwarnings("""ignore""", category=UserWarning, module="""torch.optim.lr_scheduler""")



class 					A__   :





      def __init__( self       ,							A_       ,							A_       ,							A_ = True       ,							A_ = False   ):
       '''simple docstring'''




       UpperCamelCase	:					int       	=   scheduler
       UpperCamelCase	:					Dict       	=   optimizers if isinstance(A_       ,							(list, tuple)   ) else [optimizers]
       UpperCamelCase	:					Any       	=   split_batches
       UpperCamelCase	:					Dict       	=   step_with_optimizer
       UpperCamelCase	:					Optional[int]       	=   GradientState()





      def        __UpperCamelCase( self       ,							*A_       ,							**A_   ):
       '''simple docstring'''




       if not self.step_with_optimizer:
        # No link between scheduler and optimizer -> just step
        self.scheduler.step(*A_       ,							**A_   )
        return

       # Otherwise, first make sure the optimizer was stepped.
       if not self.gradient_state.sync_gradients:
        if self.gradient_state.adjust_scheduler:
         self.scheduler._step_count += 1
        return

       for opt in self.optimizers:
        if opt.step_was_skipped:
         return
       if self.split_batches:
        # Split batches -> the training dataloader batch size is not changed so one step per training step
        self.scheduler.step(*A_       ,							**A_   )
       else:
        # Otherwise the training dataloader batch size was multiplied by `num_processes`, so we need to do
        # num_processes steps per training step
        UpperCamelCase	:					List[str]       	=   AcceleratorState().num_processes
        for _ in range(A_   ):
         # Special case when using OneCycle and `drop_last` was not used
         if hasattr(self.scheduler       ,							"total_steps"   ):
          if self.scheduler._step_count <= self.scheduler.total_steps:
           self.scheduler.step(*A_       ,							**A_   )
         else:
          self.scheduler.step(*A_       ,							**A_   )





      def        __UpperCamelCase( self   ):
       '''simple docstring'''




       return self.scheduler.get_last_lr()





      def        __UpperCamelCase( self   ):
       '''simple docstring'''




       return self.scheduler.state_dict()





      def        __UpperCamelCase( self       ,							A_   ):
       '''simple docstring'''




       self.scheduler.load_state_dict(A_   )





      def        __UpperCamelCase( self   ):
       '''simple docstring'''




       return self.scheduler.get_lr()





      def        __UpperCamelCase( self       ,							*A_       ,							**A_   ):
       '''simple docstring'''




       return self.scheduler.print_lr(*A_       ,							**A_   )







from __future__ import annotations

from functools import lru_cache
from math import ceil

__lowerCamelCase       :     str   =     100

__lowerCamelCase       :     Any   =     set(range(3, NUM_PRIMES, 2))
primes.add(2)
__lowerCamelCase       :     int

for prime in range(3, ceil(NUM_PRIMES**0.5), 2):
    if prime not in primes:
        continue
    primes.difference_update(set(range(prime * prime, NUM_PRIMES, prime)))



@lru_cache(maxsize=100     )
def 		A_				(     _lowerCAmelCase     )						-> set[int]:
 if number_to_partition < 0:
  return set()
 elif number_to_partition == 0:
  return {1}

 UpperCamelCase	:					set[int]       	=   set()
 UpperCamelCase	:					int
 UpperCamelCase	:					int

 for prime in primes:
  if prime > number_to_partition:
   continue
  for sub in partition(number_to_partition - prime     ):
   ret.add(sub * prime     )

 return ret



def 		A_				(     _lowerCAmelCase = 5000     )						-> int | None:
 for number_to_partition in range(1							,   _lowerCAmelCase     ):
  if len(partition(_lowerCAmelCase     )     ) > number_unique_partitions:
   return number_to_partition
 return None


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