





from manim import *

class      lowerCAmelCase							(      __UpperCamelCase    ):
 def   A_			(   self						:   str			)    ->			List[Any]:
     lowerCamelCase__					:   Optional[int]      				=	Rectangle(height=0.5    ,  width=0.5			)
     lowerCamelCase__					:   int      				=	Rectangle(height=0.4_6    ,  width=0.4_6			).set_stroke(width=0			)

     lowerCamelCase__					:   Optional[int]      				=	Rectangle(height=0.2_5    ,  width=0.2_5			)

     lowerCamelCase__					:   Union[str, Any]      				=	[mem.copy() for i in range(6			)]
     lowerCamelCase__					:   str      				=	[mem.copy() for i in range(6			)]
     lowerCamelCase__					:   List[str]      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   Tuple      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   Dict      				=	VGroup(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   int      				=	Text('CPU'    ,  font_size=24			)
     lowerCamelCase__					:   str      				=	Group(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0.5    ,  aligned_edge=UpperCAmelCase			)
     cpu.move_to([-2.5, -0.5, 0]			)
     self.add(UpperCAmelCase			)

     lowerCamelCase__					:   str      				=	[mem.copy() for i in range(4			)]
     lowerCamelCase__					:   Union[str, Any]      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   List[Any]      				=	Text('GPU'    ,  font_size=24			)
     lowerCamelCase__					:   Optional[int]      				=	Group(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0.5    ,  aligned_edge=UpperCAmelCase			)
     gpu.move_to([-1, -1, 0]			)
     self.add(UpperCAmelCase			)

     lowerCamelCase__					:   int      				=	[mem.copy() for i in range(6			)]
     lowerCamelCase__					:   Union[str, Any]      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)

     lowerCamelCase__					:   int      				=	Text('Model'    ,  font_size=24			)
     lowerCamelCase__					:   List[str]      				=	Group(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0.5    ,  aligned_edge=UpperCAmelCase			)
     model.move_to([3, -1.0, 0]			)
     self.add(UpperCAmelCase			)

     lowerCamelCase__					:   Union[str, Any]      				=	[]
     lowerCamelCase__					:   Optional[Any]      				=	[]

     for i, rect in enumerate(UpperCAmelCase			):
         lowerCamelCase__					:   int      				=	fill.copy().set_fill(UpperCAmelCase    ,  opacity=0.8			)
         target.move_to(UpperCAmelCase			)
         model_arr.append(UpperCAmelCase			)

         lowerCamelCase__					:   Union[str, Any]      				=	Rectangle(height=0.4_6    ,  width=0.4_6			).set_stroke(width=0.0			).set_fill(UpperCAmelCase    ,  opacity=0.8			)
         cpu_target.move_to(cpu_left_col_base[i]			)
         model_cpu_arr.append(UpperCAmelCase			)

     self.add(*UpperCAmelCase    ,  *UpperCAmelCase			)

     lowerCamelCase__					:   str      				=	[meta_mem.copy() for i in range(6			)]
     lowerCamelCase__					:   Dict      				=	[meta_mem.copy() for i in range(6			)]
     lowerCamelCase__					:   List[Any]      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   int      				=	VGroup(*UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   List[Any]      				=	VGroup(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0			)
     lowerCamelCase__					:   Optional[int]      				=	Text('Disk'    ,  font_size=24			)
     lowerCamelCase__					:   Optional[int]      				=	Group(UpperCAmelCase    ,  UpperCAmelCase			).arrange(UpperCAmelCase    ,  buff=0.5    ,  aligned_edge=UpperCAmelCase			)
     disk.move_to([-4, -1.2_5, 0]			)
     self.add(UpperCAmelCase    ,  UpperCAmelCase			)

     lowerCamelCase__					:   Optional[int]      				=	Square(side_length=2.2			)
     key.move_to([-5, 2, 0]			)

     lowerCamelCase__					:   List[Any]      				=	MarkupText(
         F"""<b>Key:</b>\n\n<span fgcolor='{YELLOW}'>●</span> Empty Model"""    ,  font_size=18    ,  )

     key_text.move_to([-5, 2.4, 0]			)

     self.add(UpperCAmelCase    ,  UpperCAmelCase			)

     lowerCamelCase__					:   Tuple      				=	MarkupText(
         F"""<span fgcolor='{BLUE}'>●</span> Checkpoint"""    ,  font_size=18    ,  )

     blue_text.next_to(UpperCAmelCase    ,  DOWN * 2.4    ,  aligned_edge=key_text.get_left()			)
     self.add(UpperCAmelCase			)

     lowerCamelCase__					:   str      				=	MarkupText(
         F"""Now watch as an input is passed through the model\nand how the memory is utilized and handled."""    ,  font_size=24    ,  )
     step_a.move_to([2, 2, 0]			)

     self.play(Write(UpperCAmelCase			)			)

     lowerCamelCase__					:   str      				=	Square(0.3			)
     input.set_fill(UpperCAmelCase    ,  opacity=1.0			)
     input.set_stroke(width=0.0			)
     input.next_to(model_base[0]    ,  UpperCAmelCase    ,  buff=0.5			)

     self.play(Write(UpperCAmelCase			)			)

     input.generate_target()
     input.target.next_to(model_arr[0]    ,  direction=UpperCAmelCase    ,  buff=0.0_2			)
     self.play(MoveToTarget(UpperCAmelCase			)			)

     self.play(FadeOut(UpperCAmelCase			)			)

     lowerCamelCase__					:   str      				=	Arrow(start=UpperCAmelCase    ,  end=UpperCAmelCase    ,  color=UpperCAmelCase    ,  buff=0.5			)
     a.next_to(model_arr[0].get_left()    ,  UpperCAmelCase    ,  buff=0.2			)

     model_cpu_arr[0].generate_target()
     model_cpu_arr[0].target.move_to(gpu_rect[0]			)

     lowerCamelCase__					:   Optional[int]      				=	MarkupText(
         F"""As the input reaches a layer, the hook triggers\nand weights are moved from the CPU\nto the GPU and back."""    ,  font_size=24    ,  )
     step_a.move_to([2, 2, 0]			)

     self.play(Write(UpperCAmelCase    ,  run_time=3			)			)

     lowerCamelCase__					:   Tuple      				=	{'run_time': 1, 'fade_in': True, 'fade_out': True, 'buff': 0.0_2}

     self.play(
         Write(UpperCAmelCase			)    ,  Circumscribe(model_arr[0]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(model_cpu_arr[0]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(gpu_rect[0]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  )
     self.play(MoveToTarget(model_cpu_arr[0]			)			)

     lowerCamelCase__					:   List[Any]      				=	a.copy()
     for i in range(6			):
         a_c.next_to(model_arr[i].get_right() + 0.0_2    ,  UpperCAmelCase    ,  buff=0.2			)

         input.generate_target()
         input.target.move_to(model_arr[i].get_right() + 0.0_2			)

         lowerCamelCase__					:   Union[str, Any]      				=	AnimationGroup(
             FadeOut(UpperCAmelCase    ,  run_time=0.5			)    ,  MoveToTarget(UpperCAmelCase    ,  run_time=0.5			)    ,  FadeIn(UpperCAmelCase    ,  run_time=0.5			)    ,  lag_ratio=0.2			)

         self.play(UpperCAmelCase			)

         model_cpu_arr[i].generate_target()
         model_cpu_arr[i].target.move_to(cpu_left_col_base[i]			)

         if i < 5:
             model_cpu_arr[i + 1].generate_target()
             model_cpu_arr[i + 1].target.move_to(gpu_rect[0]			)
             if i >= 1:
                 lowerCamelCase__					:   Union[str, Any]      				=	0.7

             self.play(
                 Circumscribe(model_arr[i]    ,  **UpperCAmelCase			)    ,  Circumscribe(cpu_left_col_base[i]    ,  **UpperCAmelCase			)    ,  Circumscribe(cpu_left_col_base[i + 1]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(gpu_rect[0]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(model_arr[i + 1]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  )
             if i < 1:
                 self.play(
                     MoveToTarget(model_cpu_arr[i]			)    ,  MoveToTarget(model_cpu_arr[i + 1]			)    ,  )
             else:
                 self.play(
                     MoveToTarget(model_cpu_arr[i]    ,  run_time=0.7			)    ,  MoveToTarget(model_cpu_arr[i + 1]    ,  run_time=0.7			)    ,  )
         else:
             model_cpu_arr[i].generate_target()
             model_cpu_arr[i].target.move_to(cpu_left_col_base[-1]			)
             input.generate_target()
             input.target.next_to(model_arr[-1].get_right()    ,  RIGHT + 0.0_2    ,  buff=0.2			)

             self.play(
                 Circumscribe(model_arr[-1]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(cpu_left_col_base[-1]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  Circumscribe(gpu_rect[0]    ,  color=UpperCAmelCase    ,  **UpperCAmelCase			)    ,  )

             self.play(MoveToTarget(model_cpu_arr[i]			)			)

         lowerCamelCase__					:   Optional[int]      				=	a_c
         lowerCamelCase__					:   Dict      				=	a_c.copy()

     input.generate_target()
     input.target.next_to(model_base[-1]    ,  RIGHT + 0.0_2    ,  buff=0.5			)
     self.play(
         FadeOut(UpperCAmelCase			)    ,  FadeOut(UpperCAmelCase    ,  run_time=0.5			)    ,  )

     lowerCamelCase__					:   Dict      				=	MarkupText(F"""Inference on a model too large for GPU memory\nis successfully completed."""    ,  font_size=24			)
     step_a.move_to([2, 2, 0]			)

     self.play(Write(UpperCAmelCase    ,  run_time=3			)    ,  MoveToTarget(UpperCAmelCase			)			)

     self.wait()












from __future__ import annotations

from collections.abc import Generator


def  SCREAMING_SNAKE_CASE   ( )    ->  Generator[int, None, None]:
    lowerCamelCase__					:   dict[int, int]      				=	{}
    lowerCamelCase__					:   Union[str, Any]      				=	2
    while True:
        lowerCamelCase__					:   Optional[int]      				=	factor_map.pop(_UpperCAmelCase		,			_UpperCAmelCase				)
        if factor:
            lowerCamelCase__					:   Optional[Any]      				=	factor + prime
            while x in factor_map:
                x += factor
            lowerCamelCase__					:   Optional[Any]      				=	factor
        else:
            lowerCamelCase__					:   Union[str, Any]      				=	prime
            yield prime
        prime += 1


def  SCREAMING_SNAKE_CASE   ( _UpperCAmelCase = 1e10				)    ->  int:
    lowerCamelCase__					:   Tuple      				=	sieve()

    lowerCamelCase__					:   Dict      				=	1
    while True:
        lowerCamelCase__					:   List[Any]      				=	next(_UpperCAmelCase				)
        if (2 * prime * n) > limit:
            return n
        # Ignore the next prime as the reminder will be 2.
        next(_UpperCAmelCase				)
        n += 2


if __name__ == "__main__":
    print(solution())





