open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = int_of_float
let i2f = float_of_int

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f =
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module JunkList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x]
      | Some [] -> Some [x]
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i

end

module L = JunkList

module JunkArray = struct
  include Array

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0

  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let concat2 = append

  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)

end

module A = JunkArray

module JunkString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = JunkString

let spsp s = S.split_on_char ' ' s

module JunkSortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = JunkSortedSet

module JunkSortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = JunkSortedMap

let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]

exception ArithmeticException of string

module JunkIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n')
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"

end

module N = JunkIntArithmetic

module JunkMatrix = struct

  type 'a t = { w : int; h : int; e : 'a array array }

  let make w h e0 =
    { w = w; h = h; e = A.make_matrix w h e0 }

  let from_columns w h e0 elems =
    let matr = make w h e0 in
    elems |> L.iteri (fun j col ->
      col |> L.iteri (fun i x -> matr.e.(i).(j) <- x));
    matr

  let blit (mats, rs, cs, w, h) (matd, rd, cd) =
    rep2 0 `Til w () 0 `Til h (fun i j ->
        matd.e.(rd + i).(cd + j) <- mats.e.(rs + i).(cs + j))

  let expand (w1, h1) (w2, h2) e0 mat =
    let matr = make w2 h2 e0 in
    blit (mat, 0, 0, w1, h1) (matr, 0, 0);
    matr

end

module M = JunkMatrix

module type FieldOps = sig
  type elt
  val zero : elt
  val one : elt
  val neg : elt -> elt
  val rcp : elt -> elt
  val add : elt -> elt -> elt
  val sub : elt -> elt -> elt
  val mul : elt -> elt -> elt
  val div : elt -> elt -> elt
end

module JunkLinearAlgebra (Fop : FieldOps) = struct

  type t = Fop.elt M.t

  let zero w h = M.make w h Fop.zero

  let prod (mat1 : t) (mat2 : t) =
    let matr = zero mat1.w mat2.h in
    rep2 0 `Til mat1.w () 0 `Til mat2.h (fun i j ->
        matr.e.(i).(j) <-
          mat1.e.(i) |> A.foldli (fun
            acc k x -> Fop.add acc (Fop.mul x mat2.e.(k).(i)))
            Fop.zero);
    matr

  exception NotZero of int
  let is_zero (mat : t) =
    try (
      rep 0 `Til mat.w (fun i ->
        if mat.e.(i) |> A.for_all (fun x -> x <> Fop.zero)
          then raise (NotZero 1)
      );
      true
    ) with _ -> false

  let col_addmul c1 (c2, a) (mat : t) =
    rep 0 `Til mat.h (fun i ->
      mat.e.(i).(c1) <- Fop.add mat.e.(i).(c1) (Fop.mul a mat.e.(i).(c2)))

  let col_inner_prod c1 c2 (mat : t) =
    let sum = ref Fop.zero in
    rep 0 `Til mat.h (fun i ->
      sum := Fop.add !sum @@ Fop.mul mat.e.(i).(c1) mat.e.(i).(c2));
    !sum

  (* let orth_extend k0 k1 mat = *)
  (*   let matx = extend (k0, h) ((k0 + k1), h) 0 mat in *)
  (*   rep k0 `Til (k0 + k1) (fun t -> *)
  (*     rep 0 `Til t (fun s ->  *)
  (*       let ip = col_inner_prod s t h matx in *)
  (*       col_addmul t (s, ip) h matx)); *)
  (*   submat (k0, 0) (k0 + k1 - 1, h - 1) matx *)

end

module type OrderedData = sig
  type t
  val compare : t -> t -> int
  val default : t
end

module JunkGraph = struct

  type 'a v_t = int * 'a
  type 'a t = { vs : 'a v_t array; nb : int Ss.t array }

  let empty nv vd =
    let vs0 = Array.make nv (0, vd) in
    for i = 0 to (nv - 1) do vs0.(i) <- (i, vd) done;
    {
      vs = vs0;
      nb = A.make nv Ss.empty
    }

  let add_edge (e : int * int) vd g =
    let (v1, v2) = e in
    g.vs.(v1 - 1) <- (v1, vd);
    g.vs.(v2 - 1) <- (v2, vd);
    g.nb.(v1 - 1) <- g.nb.(v1 - 1) |> Ss.add v2;
    g

  let add_uedge e vd g =
    add_edge e vd (add_edge (swap e) vd g)

  let from_edges nv vd es =
    es |> L.foldl (fun g e -> add_edge e vd g) (empty nv vd)

  let from_uedges nv vd es =
    es |> L.foldl (fun g e -> add_uedge e vd g) (empty nv vd)

end

module G = JunkGraph

module JunkGraphAlgorithms (Vdt : OrderedData) = struct

  type t = Vdt.t G.t

  module V = struct
    type t = int * Vdt.t
    let compare (vi1, vd1) (vi2, vd2) =
      let c1 = Vdt.compare vd1 vd2 in
      if c1 = 0 then compare vi1 vi2
      else c1

    let default i = (i, Vdt.default)
    let index (v : t) = fst v
  end

  module Vset = Ss.Make(V)

  let print_vertices label vs =
    printf "%s: " label;
    vs |> Vset.iter (fun (vi, _) -> printf "%d " vi);
    puts ""

  let nbiter (upd : V.t -> V.t -> t -> t * bool)
    (ui : int) (fr : Vset.t) (cls : int Ss.t) (g : t) =
    let nb = g.nb.(ui - 1) in
    let result = nb |> Ss.foldl (fun (ga, nxfr, nxcls) vi ->
    (* puts "nxcls: "; *)
      (* Ss.iter (fun x -> printf "%d " x) nxcls; puts ""; *)
      if ui = vi || Ss.mem vi nxcls then
        (ga, nxfr, nxcls)
      else
        let ue = g.vs.(ui - 1) and ve = g.vs.(vi - 1) in
        let (gu, close) = upd ue ve ga in
        (gu,
          nxfr |> Vset.add ve,
          if close then nxcls |> Ss.add vi else nxcls)
    ) (g, fr, cls)
    in (* puts "";  *)result

  let traverse (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (ve, fr') = Vset.pop_min fr in
      let (vi, _) = ve in
      let (gu, nxfr, nxcls) = nbiter upd vi fr' cls g' in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let frontier (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (gu, nxfr, nxcls) =
        fr |> Vset.foldl (fun (ga, nxfra, nxclsa) ve ->
          let (vi, _) = ve in
          nbiter upd vi nxfra nxclsa ga
        ) (g', Vset.empty, cls)
      in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let bfs (upd : V.t -> V.t -> t -> t) =
    frontier (fun fr cls g' -> (upd fr cls g', true))

end

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4

module Galg = JunkGraphAlgorithms (
  struct
    type t = int
    let compare = compare
    let default = 0
  end)

let print_list aa =
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa =
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let _ =
  let (n, m, k) = rdi3 () in
  let aas = rdhi () in
  let bas = rdhi () in

  let rec merge acc aas' bas' =
    match aas' with
    | [] -> (L.rev acc) @ bas'
    | ha::ta -> (
      match bas' with
      | [] -> (L.rev acc) @ aas'
      | hb::tb ->
        if ha <= hb then merge (hb::ha::acc) ta tb
        else merge (ha::hb::acc) ta tb
    )
  in

  let ma = merge [] (L.sort compare aas) (L.sort compare bas) in

  let rec sum_less_count count sum aa =
    match aa with
    | [] -> count
    | h::t ->
      if sum + h > k then count
      else sum_less_count (count + 1) (sum + h) t
  in

  puti @@ sum_less_count 0 0 ma;

();;


open Printf
open Scanf

let id x = x

let n, m, k = scanf "%d %d %d\n" (fun n m k -> n, m, k)
let aa = Array.init n (fun i -> scanf "%d " id)
let bb = Array.init m (fun i -> scanf "%d " id)

exception Break

let main () =
    let ai = ref 0 in
    let bi = ref 0 in
    let result = ref 0 in
    let total = ref 0 in
    let flag = ref true in
    try
        while !flag do
            if !ai < n && !bi < m then begin
                let ta = aa.(!ai) in
                let tb = bb.(!bi) in
                if ta < tb then begin
                    if !total + ta <= k then begin
                        total := !total + ta;
                        incr ai;
                        incr result
                    end else begin
                        raise Break
                    end
                end else begin
                    if !total + tb <= k then begin
                        total := !total + tb;
                        incr bi;
                        incr result
                    end else begin
                        raise Break
                    end
                end
            end else if !ai < n && !bi = m then begin
                let ta = aa.(!ai) in
                if !total + ta <= k then begin
                    total := !total + ta;
                    incr ai;
                    incr result
                end else begin
                    raise Break
                end
            end else if !ai = n && !bi < m then begin
                let tb = bb.(!bi) in
                 if !total + tb <= k then begin
                    total := !total + tb;
                    incr bi;
                    incr result
                end else begin
                    raise Break
                end
            end else begin
                raise Break
            end
        done
    with
        Break ->
            Printf.printf "%d\n" !result

let () = main ()

Global OOD problem IDs are disjoint from train, validation, and in-distribution test problem IDs.

Score : 300 points

Problem Statement

We have two desks: A and B. Desk A has a vertical stack of N books on it, and Desk B similarly has M books on it.

It takes us A_i minutes to read the i-th book from the top on Desk A (1 \leq i \leq N), and B_i minutes to read the i-th book from the top on Desk B (1 \leq i \leq M).

Consider the following action:

Choose a desk with a book remaining, read the topmost book on that desk, and remove it from the desk.

How many books can we read at most by repeating this action so that it takes us at most K minutes in total? We ignore the time it takes to do anything other than reading.

Constraints

1 \leq N, M \leq 200000

1 \leq K \leq 10^9

1 \leq A_i, B_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M K
A_1 A_2 \ldots A_N
B_1 B_2 \ldots B_M

Output

Print an integer representing the maximum number of books that can be read.

Sample Input 1

3 4 240
60 90 120
80 150 80 150

Sample Output 1

3

In this case, it takes us 60, 90, 120 minutes to read the 1-st, 2-nd, 3-rd books from the top on Desk A, and 80, 150, 80, 150 minutes to read the 1-st, 2-nd, 3-rd, 4-th books from the top on Desk B, respectively.

We can read three books in 230 minutes, as shown below, and this is the maximum number of books we can read within 240 minutes.

Read the topmost book on Desk A in 60 minutes, and remove that book from the desk.

Read the topmost book on Desk B in 80 minutes, and remove that book from the desk.

Read the topmost book on Desk A in 90 minutes, and remove that book from the desk.

Sample Input 2

3 4 730
60 90 120
80 150 80 150

Sample Output 2

7

Sample Input 3

5 4 1
1000000000 1000000000 1000000000 1000000000 1000000000
1000000000 1000000000 1000000000 1000000000

Sample Output 3

0

Watch out for integer overflows.

Submitted source-code file size, in bytes.

Execution CPU time reported by official Project CodeNet metadata, in milliseconds.

Peak memory usage reported by official Project CodeNet metadata, in kilobytes.


open Batteries
let n,m,k = Scanf.sscanf (read_line()) "%d %d %d" (fun n m k -> n,m,k)
let a = read_line () |> String.split_on_char ' ' |> List.map int_of_string |> Array.of_list
let b = read_line () |> String.split_on_char ' ' |> List.map int_of_string |> Array.of_list

let rec main_loop a_where b_where time_count book_count =
  if a_where >= n && b_where >= m then book_count else
  if a_where >= n then (
    if time_count + b.(b_where) > k then book_count else
    main_loop (a_where) (b_where+1) (time_count + b.(b_where)) (book_count+1)
  ) else
  if b_where >= m then (
    if time_count + a.(a_where) > k then book_count else
    main_loop (a_where+1) (b_where) (time_count + a.(a_where)) (book_count+1)
  ) else
  (
    if time_count + a.(a_where) > k then (
      if time_count + b.(b_where) > k then book_count else
      main_loop (a_where) (b_where+1) (time_count + b.(b_where)) (book_count+1)
    ) else
    max (main_loop (a_where+1) (b_where) (time_count + a.(a_where)) (book_count+1)) (main_loop (a_where) (b_where+1) (time_count + b.(b_where)) (book_count+1))
  )
let _ = Printf.printf "%d\n" @@ main_loop 0 0 0 0


open Batteries
module EnumL = Enum.Labels
module ListL = List.Labels
module ArrayL = Array.Labels

let dbg0 x = Printf.eprintf "[debug]%s\n" @@ dump x
let dbg1 x = dbg0 x; x

let id = identity

let (++) n m = if n <= m then  List.range n `To m else []
let (++-) n m = if n >= m then List.range n `Downto m else []
let (++^) n m = if n < m then List.range n `To (pred m) else []

module ModOp = struct
  let prime = 1_000_000_007
  let (-) a b = (a + prime - b) mod prime
  let (+) a b = (a + b) mod prime
  let ( * ) a b = (a * b) mod prime

  let rec pow x n =
    if n = 0 then 1
    else if n mod 2 = 0 then pow (x*x) (n/2)
    else x * pow (x*x) (n/2)
end

let scan fmt = Scanf.sscanf (read_line ()) fmt

let scan_lines n fmt f =
  if n = 0 then []
  else List.map (fun _ -> scan fmt f) (1 ++ n)

let scan_list ?sep cnv =
  let line = read_line () in
  (match sep with
   | None -> List.map String.of_char @@ String.to_list line
   | Some sep -> String.split_on_char sep line)
  |> List.map cnv

let scan_array ?sep cnv = Array.of_list @@ scan_list ?sep cnv

let scan_matrix n m e ?sep conv =
  let arr = Array.make_matrix n m e in
  ListL.iter (0 ++^ n)
    ~f:(fun i -> arr.(i) <- Array.of_list @@ scan_list ?sep conv);
  arr

let atoi c = Char.code c - Char.code '0'
let itoa n = Char.chr (n + Char.code '0')

let rec powerset = function
  | [] -> [[]]
  | hd::tl ->
    let pws =  powerset tl in
    pws @ ListL.map pws ~f:(fun pw -> hd::pw)

let permutations l =
  let rec interleave x = function
    | [] -> [[x]]
    | (hd::tl) as l ->
      (x::l) :: (interleave x tl |> ListL.map ~f:(fun l -> hd::l)) in
  let rec aux = function
    | [] -> [[]]
    | a::rest ->
      aux rest |> ListL.map ~f:(interleave a) |> List.concat in
  aux l

let intersection l =
  EnumL.filter ~f:(fun x -> EnumL.exists ~f:((=) x) @@ Enum.clone l)

let zip l m =
  let n = min (List.length l) (List.length m) in
  List.combine (List.take n l) (List.take n m)

let lower_bound n f =
  let rec aux l u =
    if u - l > 1 then
      let m = (l + u) / 2 in
      if f m then aux l m
      else aux m u
    else u in aux (-1) n

let between n x m = n <= x && x < m

let (n,m,k) = scan "%d %d %d" Tuple3.make
let a = scan_array ~sep:' ' Int.of_string
let b = scan_array ~sep:' ' Int.of_string

exception Found
let () =
  let i = ref 0 in
  let j = ref 0 in
  let sum = ref 0 in
  (try ListL.fold_left (0++^(n+m)) ~init:0 ~f:(fun prev _ ->
       if !i < n && !j < m then
         let v = min a.(!i) b.(!j) in
         if k < prev + v then raise Found
         else (incr sum; (if a.(!i) < b.(!j) then incr i else incr j); prev + v)
       else if !i < n then
         let v = a.(!i) in
         if k < prev + v then raise Found
         else (incr sum; incr i; prev + v)
       else
         let v = b.(!j) in
         if k < prev + v then raise Found
         else (incr sum; incr j; prev + v)
     ) |> ignore with _ -> ());
  Printf.printf "%d\n" !sum


Scanf.scanf "%d %d %d" (fun n m k ->
    let a = Array.init n (fun _ -> Scanf.scanf " %d" (fun a -> a)) in
    let b = Array.init m (fun _ -> Scanf.scanf " %d" (fun b -> b)) in

    let sa = Array.make (n + 1) 0 in
    let sb = Array.make (m + 1) 0 in
    for i = 0 to n - 1 do sa.(i + 1) <- sa.(i) + a.(i) done;
    for i = 0 to m - 1 do sb.(i + 1) <- sb.(i) + b.(i) done;

    let rec loop ia =
        if ia > n then n else
            if sa.(ia) <= k then loop (ia + 1) else ia - 1
    in
    let ia = loop 0 in
    let rec loop ib =
        if ib > m then m else
            if sb.(ib) + sa.(ia) <= k then loop (ib + 1) else ib - 1
    in
    let ib = loop 0 in
    let rec loop ia ib best =
        if ia < 0 || ib > m then best else
            if sa.(ia) + sb.(ib) <= k then (
                let best = max best (ia + ib) in
                loop ia (ib + 1) best
            ) else loop (ia - 1) ib best
    in
    loop ia ib (ia + ib) |> Printf.printf "%d\n"
)


let n = read_int ()
let n' = int_of_float (sqrt (float_of_int n)) + 1

let rec solve k ans =
  if k = n' then ans
  else
    let k' = n / k in
    let f = k' * k' + k' - k * k in
    solve (k + 1) (ans + k * f)

let () = Printf.printf "%d\n" (solve 1 0)

Score : 400 points

Problem Statement

For a positive integer X, let f(X) be the number of positive divisors of X.

Given a positive integer N, find \sum_{K=1}^N K\times f(K).

Constraints

1 \leq N \leq 10^7

Input

Input is given from Standard Input in the following format:

N

Output

Print the value \sum_{K=1}^N K\times f(K).

Sample Input 1

4

Sample Output 1

23

We have f(1)=1, f(2)=2, f(3)=2, and f(4)=3, so the answer is 1\times 1 + 2\times 2 + 3\times 2 + 4\times 3 =23.

Sample Input 2

100

Sample Output 2

26879

Sample Input 3

10000000

Sample Output 3

838627288460105

Watch out for overflows.


let () =
  Scanf.scanf "%d" @@ fun n ->
  let h x = x * (x + 1) / 2 in
  let rec g i a =
    if i > n then a
    else g (i + 1) (a + i * (h (n / i))) in
  Printf.printf "%d" (g 1 0)


let () =
  Scanf.scanf "%d" @@ fun n ->
  let h x = x * (x + 1) / 2 in
  let rec g i =
    if i > n then 0
    else i * (h (n / i)) + g (i + 1) in
  Printf.printf "%d" (g 1)


let () = Scanf.scanf "%d" @@ fun n ->
  let sum = ref 0 in
  for i=1 to n do
    let k = n/i in
    sum := !sum + i*k*(k+1)/2
  done;
  Printf.printf "%d\n" !sum


let n = Scanf.sscanf (read_line ()) "%d" @@ fun n -> n

let f k = let t = n / k in t * (t + 1) / 2* k

let () = Printf.printf "%d\n" @@ Array.fold_left (+) 0 @@ Array.init n @@ fun i -> f (i + 1)


let () = Scanf.scanf "%d" @@ fun n ->
  let sum = ref 0 in
  let dp = Array.make (n + 1) 0 in
  for i = 1 to n do
    let rec iter j =
      if j <= n then (dp.(j) <- j + dp.(j); iter (i + j)) in
    iter i;
    sum := !sum + dp.(i);
  done;
  Printf.printf "%d\n" !sum


let () = Scanf.scanf "%d" @@ fun n ->
  let sum = ref 1 in
  let dp = Array.make (n + 1) 1 in
  let is_prime = Array.make (n + 1) true in
  for p = 2 to n do
    if is_prime.(p) then begin
      let rec outer i pp =
        if pp <= n then begin
          let rec inner j =
            if j <= n then begin
              is_prime.(j) <- false;
              dp.(j) <- dp.(j) * (1 + i) / i;
              inner (j + pp)
            end in
          inner pp; outer (i + 1) (pp * p)
        end in
      outer 1 p;
    end;
    sum := p * dp.(p) + !sum
  done;
  Printf.printf "%d\n" !sum


Scanf.scanf "%d" (fun n ->
    let rec loop i acc =
        if i > n then acc else
            let q = n / i in
            let acc = acc + i * q * (q + 1) / 2 in
            loop (i + 1) acc
    in
    loop 1 0 |> Printf.printf "%d\n"
)


let n = Scanf.scanf "%d\n" (fun i -> i)
let a = Array.init n (fun _ -> Scanf.scanf " %d" (fun i -> i))

let m = Array.fold_left max 1 a + 1

let b1 = Array.make m false
let b2 = Array.make m false

let rec f i =
  if i < n then (
    let ai = a.(i) in
    if not b1.(ai) then (
        if b2.(ai) then
          b1.(ai) <- true
        else (
          let rec g j =
            let x = ai * j in
            if x < m then (
                b1.(x) <- true;
                g (j + 1)
            ) in
          g 2;
          b2.(ai) <- true
        )
    );
    f (i + 1)
  )

let rec g i ans =
  if i = n then ans
  else if b1.(a.(i)) then g (i + 1) ans
  else g (i + 1) (ans + 1)

let () = f 0; Printf.printf "%d\n" (g 0 0)

Score : 400 points

Problem Statement

Given is a number sequence A of length N.

Find the number of integers i \left(1 \leq i \leq N\right) with the following property:

For every integer j \left(1 \leq j \leq N\right) such that i \neq j , A_j does not divide A_i.

Constraints

All values in input are integers.

1 \leq N \leq 2 \times 10^5

1 \leq A_i \leq 10^6

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 \cdots A_N

Output

Print the answer.

Sample Input 1

5
24 11 8 3 16

Sample Output 1

3

The integers with the property are 2, 3, and 4.

Sample Input 2

4
5 5 5 5

Sample Output 2

0

Note that there can be multiple equal numbers.

Sample Input 3

10
33 18 45 28 8 19 89 86 2 4

Sample Output 3

5


let () = Scanf.scanf "%d\n" @@ fun n ->
  let cnt = Array.make 1000001 0 in
  for i=1 to n do
    Scanf.scanf " %d" @@ fun a -> cnt.(a) <- 1 + cnt.(a)
  done;
  let dp = Array.make 1000001 1 in
  for a=0 to 1000000 do
    if cnt.(a) <> 1 then dp.(a) <- 0;
    if 0 < cnt.(a) then
      let rec mark i =
        if i <= 1000000 then
          (cnt.(i) <- 0; mark (i+a)) in
      mark (a)
  done;
  Printf.printf "%d\n" @@ Array.fold_left (+) 0 dp


let () = Scanf.scanf "%d\n" @@ fun n ->
  let array = Array.init n @@ fun _ -> Scanf.scanf " %d" Fun.id in
  let () = Array.sort compare array in
  let dp = Array.make 1000010 true in
  let amax = 1000000 in
  let ans = ref 0 in
  for i=0 to n-1 do
    let a = array.(i) in
    let k = amax/a in
    if dp.(a)
    then
      begin
        if (i=0 || i>0 && array.(i-1) <> a) && (i=n-1 || i<n-1 && array.(i+1) <> a) then ans := !ans + 1
      end;
      for j=1 to k do
        dp.(a*j) <- false
      done
  done;
  Printf.printf "%d\n" !ans


open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = float_of_int
let i2f = int_of_float

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f =
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module ToyList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x]
      | Some [] -> Some [x]
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i
end

module L = ToyList

module ToyArray = struct
  include Array

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0

  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let concat2 = append

  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)
end

module A = ToyArray

module ToyString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = ToyString

let spsp s = S.split_on_char ' ' s

module ToySortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = ToySortedSet

module ToySortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = ToySortedMap

let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]

exception ArithmeticException of string

module ToyIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n')
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"

end

module N = ToyIntArithmetic

module ToyMatrix = struct

  type 'a t = { w : int; h : int; e : 'a array array }

  let make w h e0 =
    { w = w; h = h; e = A.make_matrix w h e0 }

  let from_columns w h e0 elems =
    let matr = make w h e0 in
    elems |> L.iteri (fun j col ->
      col |> L.iteri (fun i x -> matr.e.(i).(j) <- x));
    matr

  let blit (mats, rs, cs, w, h) (matd, rd, cd) =
    rep2 0 `Til w () 0 `Til h (fun i j ->
        matd.e.(rd + i).(cd + j) <- mats.e.(rs + i).(cs + j))

  let expand (w1, h1) (w2, h2) e0 mat =
    let matr = make w2 h2 e0 in
    blit (mat, 0, 0, w1, h1) (matr, 0, 0);
    matr

end

module M = ToyMatrix

module type FieldOps = sig
  type elt
  val zero : elt
  val one : elt
  val neg : elt -> elt
  val rcp : elt -> elt
  val add : elt -> elt -> elt
  val sub : elt -> elt -> elt
  val mul : elt -> elt -> elt
  val div : elt -> elt -> elt
end

module ToyLinearAlgebra (Fop : FieldOps) = struct

  type t = Fop.elt M.t

  let zero w h = M.make w h Fop.zero

  let prod (mat1 : t) (mat2 : t) =
    let matr = zero mat1.w mat2.h in
    rep2 0 `Til mat1.w () 0 `Til mat2.h (fun i j ->
        matr.e.(i).(j) <-
          mat1.e.(i) |> A.foldli (fun
            acc k x -> Fop.add acc (Fop.mul x mat2.e.(k).(i)))
            Fop.zero);
    matr

  exception NotZero of int
  let is_zero (mat : t) =
    try (
      rep 0 `Til mat.w (fun i ->
        if mat.e.(i) |> A.for_all (fun x -> x <> Fop.zero)
          then raise (NotZero 1)
      );
      true
    ) with _ -> false

  let col_addmul c1 (c2, a) (mat : t) =
    rep 0 `Til mat.h (fun i ->
      mat.e.(i).(c1) <- Fop.add mat.e.(i).(c1) (Fop.mul a mat.e.(i).(c2)))

  let col_inner_prod c1 c2 (mat : t) =
    let sum = ref Fop.zero in
    rep 0 `Til mat.h (fun i ->
      sum := Fop.add !sum @@ Fop.mul mat.e.(i).(c1) mat.e.(i).(c2));
    !sum

  (* let orth_extend k0 k1 mat = *)
  (*   let matx = extend (k0, h) ((k0 + k1), h) 0 mat in *)
  (*   rep k0 `Til (k0 + k1) (fun t -> *)
  (*     rep 0 `Til t (fun s ->  *)
  (*       let ip = col_inner_prod s t h matx in *)
  (*       col_addmul t (s, ip) h matx)); *)
  (*   submat (k0, 0) (k0 + k1 - 1, h - 1) matx *)

end

module type OrderedData = sig
  type t
  val compare : t -> t -> int
  val default : t
end

module ToyGraph = struct

  type 'a v_t = int * 'a
  type 'a t = { vs : 'a v_t array; nb : int Ss.t array }

  let empty nv vd =
    let vs0 = A.make nv (0, vd) in
    for i = 0 to (nv - 1) do vs0.(i) <- (i, vd) done;
    {
      vs = vs0;
      nb = A.make nv Ss.empty
    }

  let add_edge (e : int * int) vd g =
    let (v1, v2) = e in
    g.vs.(v1 - 1) <- (v1, vd);
    g.vs.(v2 - 1) <- (v2, vd);
    g.nb.(v1 - 1) <- g.nb.(v1 - 1) |> Ss.add v2;
    g

  let add_uedge e vd g =
    add_edge e vd (add_edge (swap e) vd g)

  let from_edges nv vd es =
    es |> L.foldl (fun g e -> add_edge e vd g) (empty nv vd)

  let from_uedges nv vd es =
    es |> L.foldl (fun g e -> add_uedge e vd g) (empty nv vd)

end

module G = ToyGraph

module ToyGraphAlgorithms (Vdt : OrderedData) = struct

  type t = Vdt.t G.t

  module V = struct
    type t = int * Vdt.t
    let compare (vi1, vd1) (vi2, vd2) =
      let c1 = Vdt.compare vd1 vd2 in
      if c1 = 0 then compare vi1 vi2
      else c1

    let default i = (i, Vdt.default)
    let index (v : t) = fst v
  end

  module Vset = Ss.Make(V)

  let print_vertices label vs =
    printf "%s: " label;
    vs |> Vset.iter (fun (vi, _) -> printf "%d " vi);
    puts ""

  let nbiter (upd : V.t -> V.t -> t -> t * bool)
    (ui : int) (fr : Vset.t) (cls : int Ss.t) (g : t) =
    let nb = g.nb.(ui - 1) in
    let result = nb |> Ss.foldl (fun (ga, nxfr, nxcls) vi ->
    (* puts "nxcls: "; *)
      (* Ss.iter (fun x -> printf "%d " x) nxcls; puts ""; *)
      if ui = vi || Ss.mem vi nxcls then
        (ga, nxfr, nxcls)
      else
        let ue = g.vs.(ui - 1) and ve = g.vs.(vi - 1) in
        let (gu, close) = upd ue ve ga in
        (gu,
          nxfr |> Vset.add ve,
          if close then nxcls |> Ss.add vi else nxcls)
    ) (g, fr, cls)
    in (* puts "";  *)result

  let traverse (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (ve, fr') = Vset.pop_min fr in
      let (vi, _) = ve in
      let (gu, nxfr, nxcls) = nbiter upd vi fr' cls g' in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let frontier (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (gu, nxfr, nxcls) =
        fr |> Vset.foldl (fun (ga, nxfra, nxclsa) ve ->
          let (vi, _) = ve in
          nbiter upd vi nxfra nxclsa ga
        ) (g', Vset.empty, cls)
      in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let bfs (upd : V.t -> V.t -> t -> t) =
    frontier (fun fr cls g' -> (upd fr cls g', true))

end

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4

module Galg = ToyGraphAlgorithms (
  struct
    type t = int
    let compare = compare
    let default = 0
  end)

let print_list aa =
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa =
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let split_array_at i aa =
  (A.take i aa, A.drop i aa)

let largest_prime_factor n =
  let rec loop ps n' =
    match ps with
    | [] -> n'
    | p::t ->
      if n' mod p = 0 then
        (if n' = p then p else loop ps (n' / p))
      else loop t n'
  in loop N.primes_le_1000 n

let findi_opt f s ar =
  let rec loop i =
  if i >= A.len ar then None
  else
    (if f ar.(i) then Some i else loop (i + 1))
  in loop s

let _ =
  let n = rdi () in
  let al = rdhi () in

  let isolate ls =
    let rec loop rs ss = function
    | [] -> (rs, ss)
    | h::t ->
      if Ss.mem h rs then loop rs (Ss.add h ss) t
      else loop (Ss.add h rs) ss t
    in loop Ss.empty Ss.empty al
  in

  let sieve_in_place s e ea thr aa =
    (* printf "sieve %d %d %d: " s e ea; *)
    (*   print_array aa; *)
    let rec sieve_by m i j =
      (* printf "sieve_by %d %d %d: " m i j; *)
      (* print_array aa; *)
      if i >= ea then ()
      else (
        let x = aa.(i) in
        if x = 0 then ()
        else if x mod m <> 0 then (
          aa.(j) <- x;
          if i > j then aa.(i) <- 0;
          sieve_by m (i + 1) (j + 1)
        ) else (
          aa.(i) <- 0;
          sieve_by m (i + 1) j
        )
      )
    in

    let rec loop k =
      (* printf "loop1 %d: " k; *)
      (* print_array aa; *)
      if k >= e - 1 then ()
      else (
        let m = aa.(k) in
        if m > thr then ()
        else (
          sieve_by m (k + 1) (k + 1);
          loop (k + 1)
        )
      )
    in

    if e - s <= 1 then ()
    else loop s
  in

  let sieve_le_1000 aa =
    let l = A.len aa in
    if l <= 1 then (aa, [||])
    else (
      A.sort compare aa;
      match findi_opt (fun x -> x >= 1000) 0 aa with
      | Some e -> (
          sieve_in_place 0 e l 1000 aa;
          match findi_opt (fun x -> x >= 1000) 0 aa with
          | Some e' ->
            (A.takeb 0 @@ A.take e' aa, A.takeb 0 @@ A.drop e' aa)
          | None -> (A.takeb 0 aa, [||])
        )
      | None ->
        sieve_in_place 0 l l 1000 aa;
        (A.takeb 0 aa, [||])
    )
  in

  let rec sieve_gt_1000 aa =
    (* printf "sieve_gt: "; print_array aa; *)
    let l = A.len aa in
    if l <= 1 then aa
    else (
      let aaf = aa |> A.map (fun x ->
        let lp = largest_prime_factor x in (lp, x))
      in
      A.sort compare aaf;
      let (aap, aas) = A.split aaf in
      (* print_array aap; *)
      (* print_array aas; *)

      let rec loop s =
        (* printf "loop2 %d " s; *)
        if s >= l then ()
        else (
          let p = aap.(s) in
          match findi_opt (fun p' -> p' > p) s aap with
          | Some e ->
            (* printf "%d:" e; print_array aas; *)
            sieve_in_place s e e 1000001 aas;
            loop e
          | None ->
            sieve_in_place s l l 1000001 aas;
            ()
        )
        (* ; puts "" *)
      in
      loop 0;
      aas |> A.filter_map (fun x -> if x = 0 then None else Some x)
    )
  in

  let (rs, ss) = isolate al in
  let aa0 = Ss.to_array rs in

  let (aa1, aar) = sieve_le_1000 aa0 in
  (* print_array aa1; *)
  (* print_array aar; *)
  let aa2 = sieve_gt_1000 aar in
  (* print_array aa2; *)
  let sieved = Ss.of_array @@ A.append aa1 aa2 in
  let result = Ss.diff sieved ss in
  (* print_array @@ Ss.to_array result; *)
  puti @@ Ss.size result
;;


open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = float_of_int
let i2f = int_of_float

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f =
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module ToyList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x]
      | Some [] -> Some [x]
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i
end

module L = ToyList

module ToyArray = struct
  include Array

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0

  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let concat2 = append

  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)
end

module A = ToyArray

module ToyString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = ToyString

let spsp s = S.split_on_char ' ' s

module ToySortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = ToySortedSet

module ToySortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = ToySortedMap

let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]

exception ArithmeticException of string

module ToyIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n')
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"

end

module N = ToyIntArithmetic

module ToyMatrix = struct

  type 'a t = { w : int; h : int; e : 'a array array }

  let make w h e0 =
    { w = w; h = h; e = A.make_matrix w h e0 }

  let from_columns w h e0 elems =
    let matr = make w h e0 in
    elems |> L.iteri (fun j col ->
      col |> L.iteri (fun i x -> matr.e.(i).(j) <- x));
    matr

  let blit (mats, rs, cs, w, h) (matd, rd, cd) =
    rep2 0 `Til w () 0 `Til h (fun i j ->
        matd.e.(rd + i).(cd + j) <- mats.e.(rs + i).(cs + j))

  let expand (w1, h1) (w2, h2) e0 mat =
    let matr = make w2 h2 e0 in
    blit (mat, 0, 0, w1, h1) (matr, 0, 0);
    matr

end

module M = ToyMatrix

module type FieldOps = sig
  type elt
  val zero : elt
  val one : elt
  val neg : elt -> elt
  val rcp : elt -> elt
  val add : elt -> elt -> elt
  val sub : elt -> elt -> elt
  val mul : elt -> elt -> elt
  val div : elt -> elt -> elt
end

module ToyLinearAlgebra (Fop : FieldOps) = struct

  type t = Fop.elt M.t

  let zero w h = M.make w h Fop.zero

  let prod (mat1 : t) (mat2 : t) =
    let matr = zero mat1.w mat2.h in
    rep2 0 `Til mat1.w () 0 `Til mat2.h (fun i j ->
        matr.e.(i).(j) <-
          mat1.e.(i) |> A.foldli (fun
            acc k x -> Fop.add acc (Fop.mul x mat2.e.(k).(i)))
            Fop.zero);
    matr

  exception NotZero of int
  let is_zero (mat : t) =
    try (
      rep 0 `Til mat.w (fun i ->
        if mat.e.(i) |> A.for_all (fun x -> x <> Fop.zero)
          then raise (NotZero 1)
      );
      true
    ) with _ -> false

  let col_addmul c1 (c2, a) (mat : t) =
    rep 0 `Til mat.h (fun i ->
      mat.e.(i).(c1) <- Fop.add mat.e.(i).(c1) (Fop.mul a mat.e.(i).(c2)))

  let col_inner_prod c1 c2 (mat : t) =
    let sum = ref Fop.zero in
    rep 0 `Til mat.h (fun i ->
      sum := Fop.add !sum @@ Fop.mul mat.e.(i).(c1) mat.e.(i).(c2));
    !sum

  (* let orth_extend k0 k1 mat = *)
  (*   let matx = extend (k0, h) ((k0 + k1), h) 0 mat in *)
  (*   rep k0 `Til (k0 + k1) (fun t -> *)
  (*     rep 0 `Til t (fun s ->  *)
  (*       let ip = col_inner_prod s t h matx in *)
  (*       col_addmul t (s, ip) h matx)); *)
  (*   submat (k0, 0) (k0 + k1 - 1, h - 1) matx *)

end

module type OrderedData = sig
  type t
  val compare : t -> t -> int
  val default : t
end

module ToyGraph = struct

  type 'a v_t = int * 'a
  type 'a t = { vs : 'a v_t array; nb : int Ss.t array }

  let empty nv vd =
    let vs0 = A.make nv (0, vd) in
    for i = 0 to (nv - 1) do vs0.(i) <- (i, vd) done;
    {
      vs = vs0;
      nb = A.make nv Ss.empty
    }

  let add_edge (e : int * int) vd g =
    let (v1, v2) = e in
    g.vs.(v1 - 1) <- (v1, vd);
    g.vs.(v2 - 1) <- (v2, vd);
    g.nb.(v1 - 1) <- g.nb.(v1 - 1) |> Ss.add v2;
    g

  let add_uedge e vd g =
    add_edge e vd (add_edge (swap e) vd g)

  let from_edges nv vd es =
    es |> L.foldl (fun g e -> add_edge e vd g) (empty nv vd)

  let from_uedges nv vd es =
    es |> L.foldl (fun g e -> add_uedge e vd g) (empty nv vd)

end

module G = ToyGraph

module ToyGraphAlgorithms (Vdt : OrderedData) = struct

  type t = Vdt.t G.t

  module V = struct
    type t = int * Vdt.t
    let compare (vi1, vd1) (vi2, vd2) =
      let c1 = Vdt.compare vd1 vd2 in
      if c1 = 0 then compare vi1 vi2
      else c1

    let default i = (i, Vdt.default)
    let index (v : t) = fst v
  end

  module Vset = Ss.Make(V)

  let print_vertices label vs =
    printf "%s: " label;
    vs |> Vset.iter (fun (vi, _) -> printf "%d " vi);
    puts ""

  let nbiter (upd : V.t -> V.t -> t -> t * bool)
    (ui : int) (fr : Vset.t) (cls : int Ss.t) (g : t) =
    let nb = g.nb.(ui - 1) in
    let result = nb |> Ss.foldl (fun (ga, nxfr, nxcls) vi ->
    (* puts "nxcls: "; *)
      (* Ss.iter (fun x -> printf "%d " x) nxcls; puts ""; *)
      if ui = vi || Ss.mem vi nxcls then
        (ga, nxfr, nxcls)
      else
        let ue = g.vs.(ui - 1) and ve = g.vs.(vi - 1) in
        let (gu, close) = upd ue ve ga in
        (gu,
          nxfr |> Vset.add ve,
          if close then nxcls |> Ss.add vi else nxcls)
    ) (g, fr, cls)
    in (* puts "";  *)result

  let traverse (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (ve, fr') = Vset.pop_min fr in
      let (vi, _) = ve in
      let (gu, nxfr, nxcls) = nbiter upd vi fr' cls g' in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let frontier (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (gu, nxfr, nxcls) =
        fr |> Vset.foldl (fun (ga, nxfra, nxclsa) ve ->
          let (vi, _) = ve in
          nbiter upd vi nxfra nxclsa ga
        ) (g', Vset.empty, cls)
      in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let bfs (upd : V.t -> V.t -> t -> t) =
    frontier (fun fr cls g' -> (upd fr cls g', true))

end

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4

module Galg = ToyGraphAlgorithms (
  struct
    type t = int
    let compare = compare
    let default = 0
  end)

let print_list aa =
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa =
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let split_array_at i aa =
  (A.take i aa, A.drop i aa)

let largest_prime_factor n =
  let rec loop ps n' =
    match ps with
    | [] -> n'
    | p::t ->
      if n' mod p = 0 then
        (if n' = p then p else loop ps (n' / p))
      else loop t n'
  in loop N.primes_le_1000 n

let findi_opt f s ar =
  let rec loop i =
  if i >= A.len ar then None
  else
    (if f ar.(i) then Some i else loop (i + 1))
  in loop s

let _ =
  let n = rdi () in
  let al = rdhi () in

  let isolate ls =
    let rec loop rs ss = function
    | [] -> (rs, ss)
    | h::t ->
      if Ss.mem h rs then loop rs (Ss.add h ss) t
      else loop (Ss.add h rs) ss t
    in loop Ss.empty Ss.empty al
  in

  let sieve_in_place s e thr aa =
    (* printf "sieve %d %d: " s e; *)
    (*   print_array aa; *)
    let rec sieve_by m i j =
      (* printf "sieve_by %d %d %d: " m i j; *)
      (* print_array aa; *)
      if i >= e then ()
      else (
        let x = aa.(i) in
        if x = 0 then ()
        else if x mod m <> 0 then (
          aa.(j) <- x;
          if i > j then aa.(i) <- 0;
          sieve_by m (i + 1) (j + 1)
        ) else (
          aa.(i) <- 0;
          sieve_by m (i + 1) j
        )
      )
    in

    let rec loop k =
      (* printf "loop1 %d: " k; *)
      (* print_array aa; *)
      if k >= e - 1 then ()
      else (
        let m = aa.(k) in
        if m > thr then ()
        else (
          sieve_by m (k + 1) (k + 1);
          loop (k + 1)
        )
      )
    in

    if e - s <= 1 then ()
    else loop s
  in

  let sieve_le_1000 aa =
    if A.len aa <= 1 then (aa, [||])
    else (
      A.sort compare aa;
      match findi_opt (fun x -> x > 1000) 0 aa with
      | Some e ->
        let aa1 = A.take (e + 1) aa and aa2 = A.drop e aa in
        sieve_in_place 0 e 1000 aa1;
        (A.takeb 0 aa1, aa2)
      | None ->
        sieve_in_place 0 (A.len aa) 1000 aa;
        (A.takeb 0 aa, [||])
    )
  in

  let rec sieve_gt_1000 aa =
    if A.len aa <= 1 then aa
    else (
      let aaf = aa |> A.map (fun x ->
        let lp = largest_prime_factor x in (lp, x))
      in
      A.sort compare aaf;
      let (aap, aas) = A.split aaf in
      (* print_array aap; *)
      (* print_array aas; *)

      let rec loop s =
        (* printf "loop2 %d " s; *)
        if s >= A.len aaf then ()
        else (
          let p = aap.(s) in
          match findi_opt (fun p' -> p' > p) s aap with
          | Some e ->
            (* printf "%d:" e; print_array aas; *)
            sieve_in_place s e 1000001 aas;
            loop e
          | None ->
            sieve_in_place s (A.len aas) 1000001 aas;
            ()
        )
        (* ; puts "" *)
      in
      loop 0;
      aas |> A.filter_map (fun x -> if x = 0 then None else Some x)
    )
  in

  let (rs, ss) = isolate al in
  let aa0 = Ss.to_array rs in

  let (aa1, aar) = sieve_le_1000 aa0 in
  let aa2 = sieve_gt_1000 aar in
  (* print_array aa1; *)
  (* print_array aa2; *)
  let sieved = Ss.of_array @@ A.append aa1 aa2 in
  let result = Ss.diff sieved ss in
  (* print_array @@ Ss.to_array result; *)
  puti @@ Ss.size result
;;


open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = float_of_int
let i2f = int_of_float

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f =
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module ToyList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x]
      | Some [] -> Some [x]
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i
end

module L = ToyList

module ToyArray = struct
  include Array

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0

  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let concat2 = append

  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)
end

module A = ToyArray

module ToyString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = ToyString

let spsp s = S.split_on_char ' ' s

module ToySortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = ToySortedSet

module ToySortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = ToySortedMap

let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]

exception ArithmeticException of string

module ToyIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n')
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"

end

module N = ToyIntArithmetic

module ToyMatrix = struct

  type 'a t = { w : int; h : int; e : 'a array array }

  let make w h e0 =
    { w = w; h = h; e = A.make_matrix w h e0 }

  let from_columns w h e0 elems =
    let matr = make w h e0 in
    elems |> L.iteri (fun j col ->
      col |> L.iteri (fun i x -> matr.e.(i).(j) <- x));
    matr

  let blit (mats, rs, cs, w, h) (matd, rd, cd) =
    rep2 0 `Til w () 0 `Til h (fun i j ->
        matd.e.(rd + i).(cd + j) <- mats.e.(rs + i).(cs + j))

  let expand (w1, h1) (w2, h2) e0 mat =
    let matr = make w2 h2 e0 in
    blit (mat, 0, 0, w1, h1) (matr, 0, 0);
    matr

end

module M = ToyMatrix

module type FieldOps = sig
  type elt
  val zero : elt
  val one : elt
  val neg : elt -> elt
  val rcp : elt -> elt
  val add : elt -> elt -> elt
  val sub : elt -> elt -> elt
  val mul : elt -> elt -> elt
  val div : elt -> elt -> elt
end

module ToyLinearAlgebra (Fop : FieldOps) = struct

  type t = Fop.elt M.t

  let zero w h = M.make w h Fop.zero

  let prod (mat1 : t) (mat2 : t) =
    let matr = zero mat1.w mat2.h in
    rep2 0 `Til mat1.w () 0 `Til mat2.h (fun i j ->
        matr.e.(i).(j) <-
          mat1.e.(i) |> A.foldli (fun
            acc k x -> Fop.add acc (Fop.mul x mat2.e.(k).(i)))
            Fop.zero);
    matr

  exception NotZero of int
  let is_zero (mat : t) =
    try (
      rep 0 `Til mat.w (fun i ->
        if mat.e.(i) |> A.for_all (fun x -> x <> Fop.zero)
          then raise (NotZero 1)
      );
      true
    ) with _ -> false

  let col_addmul c1 (c2, a) (mat : t) =
    rep 0 `Til mat.h (fun i ->
      mat.e.(i).(c1) <- Fop.add mat.e.(i).(c1) (Fop.mul a mat.e.(i).(c2)))

  let col_inner_prod c1 c2 (mat : t) =
    let sum = ref Fop.zero in
    rep 0 `Til mat.h (fun i ->
      sum := Fop.add !sum @@ Fop.mul mat.e.(i).(c1) mat.e.(i).(c2));
    !sum

  (* let orth_extend k0 k1 mat = *)
  (*   let matx = extend (k0, h) ((k0 + k1), h) 0 mat in *)
  (*   rep k0 `Til (k0 + k1) (fun t -> *)
  (*     rep 0 `Til t (fun s ->  *)
  (*       let ip = col_inner_prod s t h matx in *)
  (*       col_addmul t (s, ip) h matx)); *)
  (*   submat (k0, 0) (k0 + k1 - 1, h - 1) matx *)

end

module type OrderedData = sig
  type t
  val compare : t -> t -> int
  val default : t
end

module ToyGraph = struct

  type 'a v_t = int * 'a
  type 'a t = { vs : 'a v_t array; nb : int Ss.t array }

  let empty nv vd =
    let vs0 = A.make nv (0, vd) in
    for i = 0 to (nv - 1) do vs0.(i) <- (i, vd) done;
    {
      vs = vs0;
      nb = A.make nv Ss.empty
    }

  let add_edge (e : int * int) vd g =
    let (v1, v2) = e in
    g.vs.(v1 - 1) <- (v1, vd);
    g.vs.(v2 - 1) <- (v2, vd);
    g.nb.(v1 - 1) <- g.nb.(v1 - 1) |> Ss.add v2;
    g

  let add_uedge e vd g =
    add_edge e vd (add_edge (swap e) vd g)

  let from_edges nv vd es =
    es |> L.foldl (fun g e -> add_edge e vd g) (empty nv vd)

  let from_uedges nv vd es =
    es |> L.foldl (fun g e -> add_uedge e vd g) (empty nv vd)

end

module G = ToyGraph

module ToyGraphAlgorithms (Vdt : OrderedData) = struct

  type t = Vdt.t G.t

  module V = struct
    type t = int * Vdt.t
    let compare (vi1, vd1) (vi2, vd2) =
      let c1 = Vdt.compare vd1 vd2 in
      if c1 = 0 then compare vi1 vi2
      else c1

    let default i = (i, Vdt.default)
    let index (v : t) = fst v
  end

  module Vset = Ss.Make(V)

  let print_vertices label vs =
    printf "%s: " label;
    vs |> Vset.iter (fun (vi, _) -> printf "%d " vi);
    puts ""

  let nbiter (upd : V.t -> V.t -> t -> t * bool)
    (ui : int) (fr : Vset.t) (cls : int Ss.t) (g : t) =
    let nb = g.nb.(ui - 1) in
    let result = nb |> Ss.foldl (fun (ga, nxfr, nxcls) vi ->
    (* puts "nxcls: "; *)
      (* Ss.iter (fun x -> printf "%d " x) nxcls; puts ""; *)
      if ui = vi || Ss.mem vi nxcls then
        (ga, nxfr, nxcls)
      else
        let ue = g.vs.(ui - 1) and ve = g.vs.(vi - 1) in
        let (gu, close) = upd ue ve ga in
        (gu,
          nxfr |> Vset.add ve,
          if close then nxcls |> Ss.add vi else nxcls)
    ) (g, fr, cls)
    in (* puts "";  *)result

  let traverse (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (ve, fr') = Vset.pop_min fr in
      let (vi, _) = ve in
      let (gu, nxfr, nxcls) = nbiter upd vi fr' cls g' in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let frontier (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (gu, nxfr, nxcls) =
        fr |> Vset.foldl (fun (ga, nxfra, nxclsa) ve ->
          let (vi, _) = ve in
          nbiter upd vi nxfra nxclsa ga
        ) (g', Vset.empty, cls)
      in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let bfs (upd : V.t -> V.t -> t -> t) =
    frontier (fun fr cls g' -> (upd fr cls g', true))

end

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4

module Galg = ToyGraphAlgorithms (
  struct
    type t = int
    let compare = compare
    let default = 0
  end)

let print_list aa =
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa =
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let split_array_at i aa =
  (A.take i aa, A.drop i aa)

let largest_prime_factor n =
  let rec loop ps n' =
    match ps with
    | [] -> n'
    | p::t ->
      if n' mod p = 0 then
        (if n' = p then p else loop ps (n' / p))
      else loop t n'
  in loop N.primes_le_1000 n

let findi_opt f s ar =
  let rec loop i =
  if i >= A.len ar then None
  else
    (if f ar.(i) then Some i else loop (i + 1))
  in loop s

let _ =
  let n = rdi () in
  let al = rdhi () in

  let isolate ls =
    let rec loop rs ss = function
    | [] -> (rs, ss)
    | h::t ->
      if Ss.mem h rs then loop rs (Ss.add h ss) t
      else loop (Ss.add h rs) ss t
    in loop Ss.empty Ss.empty al
  in

  let sieve_in_place s e thr aa =
    (* printf "sieve %d %d: " s e; *)
    (*   print_array aa; *)
    let rec sieve_by m i j =
      (* printf "sieve_by %d %d %d: " m i j; *)
      (* print_array aa; *)
      if i >= e then ()
      else (
        let x = aa.(i) in
        if x = 0 then ()
        else if x mod m <> 0 then (
          aa.(j) <- x;
          if i > j then aa.(i) <- 0;
          sieve_by m (i + 1) (j + 1)
        ) else (
          aa.(i) <- 0;
          sieve_by m (i + 1) j
        )
      )
    in

    let rec loop k =
      (* printf "loop1 %d: " k; *)
      (* print_array aa; *)
      if k >= e - 1 then ()
      else (
        let m = aa.(k) in
        if m > thr then ()
        else (
          sieve_by m (k + 1) (k + 1);
          loop (k + 1)
        )
      )
    in

    if e - s <= 1 then ()
    else loop s
  in

  let sieve_le_1000 aa =
    if A.len aa <= 1 then (aa, [||])
    else (
      A.sort compare aa;
      match findi_opt (fun x -> x > 1000) 0 aa with
      | Some e ->
        let aa1 = A.take e aa and aa2 = A.drop e aa in
        sieve_in_place 0 e 1000 aa1;
        (A.takeb 0 aa1, aa2)
      | None ->
        sieve_in_place 0 (A.len aa) 1000 aa;
        (A.takeb 0 aa, [||])
    )
  in

  let rec sieve_gt_1000 aa =
    if A.len aa <= 1 then aa
    else (
      let aaf = aa |> A.map (fun x ->
        let lp = largest_prime_factor x in (lp, x))
      in
      A.sort compare aaf;
      let (aap, aas) = A.split aaf in
      (* print_array aap; *)
      (* print_array aas; *)

      let rec loop s =
        (* printf "loop2 %d " s; *)
        if s >= A.len aaf then ()
        else (
          let p = aap.(s) in
          match findi_opt (fun p' -> p' > p) s aap with
          | Some e ->
            (* printf "%d:" e; print_array aas; *)
            sieve_in_place s e 1000001 aas;
            loop e
          | None ->
            sieve_in_place s (A.len aas) 1000001 aas;
            ()
        )
        (* ; puts "" *)
      in
      loop 0;
      aas |> A.filter_map (fun x -> if x = 0 then None else Some x)
    )
  in

  let (rs, ss) = isolate al in
  let aa0 = Ss.to_array rs in

  let (aa1, aar) = sieve_le_1000 aa0 in
  let aa2 = sieve_gt_1000 aar in
  (* print_array aa1; *)
  (* print_array aa2; *)
  let sieved = Ss.of_array @@ A.append aa1 aa2 in
  let result = Ss.diff sieved ss in
  (* print_array @@ Ss.to_array result; *)
  puti @@ Ss.size result
;;


open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let c2i = int_of_char
let i2c = char_of_int
let f2i = float_of_int
let i2f = int_of_float

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putyn b = puts (if b then "Yes" else "No")
let puti i = puts @@ i2s i

let rep lb bnd ub f = match bnd with
  | `To -> for i = lb to ub do f i done
  | `Til -> for i = lb to (ub - 1) do f i done

let rep2 lb1 bnd1 ub1 () lb2 bnd2 ub2 f =
  match (bnd1, bnd2) with
  | (`To, `To) -> for i = lb1 to ub1 do for j = lb2 to ub2 do f i j done done
  | (`To, `Til) -> for i = lb1 to ub1 do for j = lb2 to (ub2 - 1) do f i j done done
  | (`Til, `To) -> for i = lb1 to (ub1 - 1) do for j = lb2 to ub2 do f i j done done
  | (`Til, `Til) -> for i = lb1 to (ub1 - 1) do for j = lb2 to (ub2 - 1) do f i j done done

module ToyList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x]
      | Some [] -> Some [x]
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i
end

module L = ToyList

module ToyArray = struct
  include Array

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0

  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)

  let concat2 = append

  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)
end

module A = ToyArray

module ToyString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = ToyString

let spsp s = S.split_on_char ' ' s

module ToySortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = ToySortedSet

module ToySortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = ToySortedMap

let set_power ls =
  let rec loop ls pls =
    match ls with
    | [] -> pls
    | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
  in loop ls [[]]

exception ArithmeticException of string

module ToyIntArithmetic = struct

  let rec power x e =
    if e = 0 then x
    else
      let rec loop r x2 e' =
        if e' = 0 then r
        else if e' land 1 = 0 then loop r (x2 * x2) (e' lsr 1)
        else loop (r * x2) (x2 * x2) (e' lsr 1)
      in loop 1 x e

  let rec powers_le_1000 x =
    if x > 32 then [x]
    else
      L.init 9 (fun e -> power x (e + 1))
      |> L.filter (fun y -> y < 1000)

  let primes_le_1000 = [2;3;5;7;11;13;17;19;23;29;31;37;41;
    43;47;53;59;61;67;71;73;79;83;89;97;101;
    103;107;109;113;127;131;137;139;149;151;157;163;167;
    173;179;181;191;193;197;199;211;223;227;229;233;239;
    241;251;257;263;269;271;277;281;283;293;307;311;313;
    317;331;337;347;349;353;359;367;373;379;383;389;397;
    401;409;419;421;431;433;439;443;449;457;461;463;467;
    479;487;491;499;503;509;521;523;541;547;557;563;569;
    571;577;587;593;599;601;607;613;617;619;631;641;643;
    647;653;659;661;673;677;683;691;701;709;719;727;733;
    739;743;751;757;761;769;773;787;797;809;811;821;823;
    827;829;839;853;857;859;863;877;881;883;887;907;911;
    919;929;937;941;947;953;967;971;977;983;991;997]

    let primes_and_powers_le_1000 =
      [2;3;4;5;7;8;9;11;13;16;17;19;23;25;27;29;31;32;37;41;
      43;47;49;53;59;61;64;67;71;73;79;81;83;89;97;
      101;103;107;109;113;121;125;127;128;131;137;139;149;151;
      157;163;167;169;173;179;181;191;193;197;199;211;223;227;
      229;233;239;241;243;251;256;257;263;269;271;277;281;283;
      289;293;307;311;313;317;331;337;343;347;349;353;359;361;
      367;373;379;383;389;397;401;409;419;421;431;433;439;443;
      449;457;461;463;467;479;487;491;499;503;509;512;521;523;
      529;541;547;557;563;569;571;577;587;593;599;601;607;613;
      617;619;625;631;641;643;647;653;659;661;673;677;683;691;
      701;709;719;727;729;733;739;743;751;757;761;769;773;787;
      797;809;811;821;823;827;829;839;841;853;857;859;863;877;
      881;883;887;907;911;919;929;937;941;947;953;961;967;971;
      977;983;991;997]

  let factorize_with ps n =
    let rec loop acc ps e n' =
      if n' <= 1 then ([], n')
      else
        match ps with
        | [] -> (acc, n')
        | p::t ->
          let r = n' mod p in
          if r = 0 then (
            if n' = p then ((p, e + 1) :: acc, 1)
            else loop acc ps (e + 1) (n' / p)
          ) else
            loop (if e = 0 then acc else (p, e) :: acc) t 0 n'
    in
    let (fs, r) = loop [] ps 0 n in
    (L.rev fs, r)

  let factorize_le_million n =
    factorize_with primes_le_1000 n

  let rec to_bits_le n =
    if n = 0 then []
    else (n mod 2) :: to_bits_le (n lsr 1)

  let rec gcd x y =
    match x mod y with
    | 0 -> y
    | z -> gcd y z

  let ext_euclid a b =
    let rec next (r0, s0, t0) (r1, s1, t1) =
      match r1 with
      | 0 -> (r0, s0, t0)
      | r2 ->
        let q = r0 / r1 in
        next (r1, s1, t1) (r0 - q * r1, s0 - q * s1, t0 - q * t1)
    in
    if a < b then
      let (g, y, x) = next (b, 1, 0) (a, 0, 1) in (g, x, y)
    else
      next (a, 1, 0) (b, 0, 1)

  let modinv x m =
    let (g, y, z) = ext_euclid x m in
    match g with
    | 1 -> y mod m
    | _ -> raise @@ ArithmeticException "Not relatively prime"

end

module N = ToyIntArithmetic

module ToyMatrix = struct

  type 'a t = { w : int; h : int; e : 'a array array }

  let make w h e0 =
    { w = w; h = h; e = A.make_matrix w h e0 }

  let from_columns w h e0 elems =
    let matr = make w h e0 in
    elems |> L.iteri (fun j col ->
      col |> L.iteri (fun i x -> matr.e.(i).(j) <- x));
    matr

  let blit (mats, rs, cs, w, h) (matd, rd, cd) =
    rep2 0 `Til w () 0 `Til h (fun i j ->
        matd.e.(rd + i).(cd + j) <- mats.e.(rs + i).(cs + j))

  let expand (w1, h1) (w2, h2) e0 mat =
    let matr = make w2 h2 e0 in
    blit (mat, 0, 0, w1, h1) (matr, 0, 0);
    matr

end

module M = ToyMatrix

module type FieldOps = sig
  type elt
  val zero : elt
  val one : elt
  val neg : elt -> elt
  val rcp : elt -> elt
  val add : elt -> elt -> elt
  val sub : elt -> elt -> elt
  val mul : elt -> elt -> elt
  val div : elt -> elt -> elt
end

module ToyLinearAlgebra (Fop : FieldOps) = struct

  type t = Fop.elt M.t

  let zero w h = M.make w h Fop.zero

  let prod (mat1 : t) (mat2 : t) =
    let matr = zero mat1.w mat2.h in
    rep2 0 `Til mat1.w () 0 `Til mat2.h (fun i j ->
        matr.e.(i).(j) <-
          mat1.e.(i) |> A.foldli (fun
            acc k x -> Fop.add acc (Fop.mul x mat2.e.(k).(i)))
            Fop.zero);
    matr

  exception NotZero of int
  let is_zero (mat : t) =
    try (
      rep 0 `Til mat.w (fun i ->
        if mat.e.(i) |> A.for_all (fun x -> x <> Fop.zero)
          then raise (NotZero 1)
      );
      true
    ) with _ -> false

  let col_addmul c1 (c2, a) (mat : t) =
    rep 0 `Til mat.h (fun i ->
      mat.e.(i).(c1) <- Fop.add mat.e.(i).(c1) (Fop.mul a mat.e.(i).(c2)))

  let col_inner_prod c1 c2 (mat : t) =
    let sum = ref Fop.zero in
    rep 0 `Til mat.h (fun i ->
      sum := Fop.add !sum @@ Fop.mul mat.e.(i).(c1) mat.e.(i).(c2));
    !sum

  (* let orth_extend k0 k1 mat = *)
  (*   let matx = extend (k0, h) ((k0 + k1), h) 0 mat in *)
  (*   rep k0 `Til (k0 + k1) (fun t -> *)
  (*     rep 0 `Til t (fun s ->  *)
  (*       let ip = col_inner_prod s t h matx in *)
  (*       col_addmul t (s, ip) h matx)); *)
  (*   submat (k0, 0) (k0 + k1 - 1, h - 1) matx *)

end

module type OrderedData = sig
  type t
  val compare : t -> t -> int
  val default : t
end

module ToyGraph = struct

  type 'a v_t = int * 'a
  type 'a t = { vs : 'a v_t array; nb : int Ss.t array }

  let empty nv vd =
    let vs0 = A.make nv (0, vd) in
    for i = 0 to (nv - 1) do vs0.(i) <- (i, vd) done;
    {
      vs = vs0;
      nb = A.make nv Ss.empty
    }

  let add_edge (e : int * int) vd g =
    let (v1, v2) = e in
    g.vs.(v1 - 1) <- (v1, vd);
    g.vs.(v2 - 1) <- (v2, vd);
    g.nb.(v1 - 1) <- g.nb.(v1 - 1) |> Ss.add v2;
    g

  let add_uedge e vd g =
    add_edge e vd (add_edge (swap e) vd g)

  let from_edges nv vd es =
    es |> L.foldl (fun g e -> add_edge e vd g) (empty nv vd)

  let from_uedges nv vd es =
    es |> L.foldl (fun g e -> add_uedge e vd g) (empty nv vd)

end

module G = ToyGraph

module ToyGraphAlgorithms (Vdt : OrderedData) = struct

  type t = Vdt.t G.t

  module V = struct
    type t = int * Vdt.t
    let compare (vi1, vd1) (vi2, vd2) =
      let c1 = Vdt.compare vd1 vd2 in
      if c1 = 0 then compare vi1 vi2
      else c1

    let default i = (i, Vdt.default)
    let index (v : t) = fst v
  end

  module Vset = Ss.Make(V)

  let print_vertices label vs =
    printf "%s: " label;
    vs |> Vset.iter (fun (vi, _) -> printf "%d " vi);
    puts ""

  let nbiter (upd : V.t -> V.t -> t -> t * bool)
    (ui : int) (fr : Vset.t) (cls : int Ss.t) (g : t) =
    let nb = g.nb.(ui - 1) in
    let result = nb |> Ss.foldl (fun (ga, nxfr, nxcls) vi ->
    (* puts "nxcls: "; *)
      (* Ss.iter (fun x -> printf "%d " x) nxcls; puts ""; *)
      if ui = vi || Ss.mem vi nxcls then
        (ga, nxfr, nxcls)
      else
        let ue = g.vs.(ui - 1) and ve = g.vs.(vi - 1) in
        let (gu, close) = upd ue ve ga in
        (gu,
          nxfr |> Vset.add ve,
          if close then nxcls |> Ss.add vi else nxcls)
    ) (g, fr, cls)
    in (* puts "";  *)result

  let traverse (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (ve, fr') = Vset.pop_min fr in
      let (vi, _) = ve in
      let (gu, nxfr, nxcls) = nbiter upd vi fr' cls g' in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let frontier (upd : V.t -> V.t -> t -> t * bool)
    (fr0 : Vset.t) (cls0 : int Ss.t) (g : t) =

    let rec progress fr cls g' =
      let (gu, nxfr, nxcls) =
        fr |> Vset.foldl (fun (ga, nxfra, nxclsa) ve ->
          let (vi, _) = ve in
          nbiter upd vi nxfra nxclsa ga
        ) (g', Vset.empty, cls)
      in
      if Vset.is_empty nxfr then (gu, nxcls)
      else progress nxfr nxcls gu
    in
    progress fr0 cls0 g

  let bfs (upd : V.t -> V.t -> t -> t) =
    frontier (fun fr cls g' -> (upd fr cls g', true))

end

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4

module Galg = ToyGraphAlgorithms (
  struct
    type t = int
    let compare = compare
    let default = 0
  end)

let print_list aa =
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa =
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let split_array_at i aa =
  (A.take i aa, A.drop i aa)

let largest_prime_factor n =
  let rec loop ps n' =
    match ps with
    | [] -> n'
    | p::t ->
      if n' mod p = 0 then
        (if n' = p then p else loop ps (n' / p))
      else loop t n'
  in loop N.primes_le_1000 n

let findi_opt f s ar =
  let rec loop i =
  if i >= A.len ar then None
  else
    (if f ar.(i) then Some i else loop (i + 1))
  in loop s

let _ =
  let n = rdi () in
  let al = rdhi () in

  let isolate ls =
    let rec loop rs ss = function
    | [] -> (rs, ss)
    | h::t ->
      if Ss.mem h rs then loop rs (Ss.add h ss) t
      else loop (Ss.add h rs) ss t
    in loop Ss.empty Ss.empty al
  in

  let sieve_in_place s e thr aa =
    (* printf "sieve %d %d: " s e; *)
    (*   print_array aa; *)
    let rec sieve_by m i j =
      (* printf "sieve_by %d %d %d: " m i j; *)
      (* print_array aa; *)
      if i >= e then ()
      else (
        let x = aa.(i) in
        if x = 0 then ()
        else if x mod m <> 0 then (
          aa.(j) <- x;
          if i > j then aa.(i) <- 0;
          sieve_by m (i + 1) (j + 1)
        ) else (
          aa.(i) <- 0;
          sieve_by m (i + 1) j
        )
      )
    in

    let rec loop k =
      (* printf "loop1 %d: " k; *)
      (* print_array aa; *)
      if k >= e - 1 then ()
      else (
        let m = aa.(k) in
        if m > thr then ()
        else (
          sieve_by m (k + 1) (k + 1);
          loop (k + 1)
        )
      )
    in

    if e - s <= 1 then ()
    else loop s
  in

  let sieve_le_1000 aa =
    if A.len aa <= 1 then (aa, [||])
    else (
      A.sort compare aa;
      match findi_opt (fun x -> x > 1000) 0 aa with
      | Some e ->
        let aa1 = A.take e aa and aa2 = A.drop e aa in
        sieve_in_place 0 e 1000 aa1;
        (A.takeb 0 aa1, aa2)
      | None ->
        sieve_in_place 0 (A.len aa) 1000 aa;
        (A.takeb 0 aa, [||])
    )
  in

  let rec sieve_gt_1000 aa =
    if A.len aa <= 1 then aa
    else (
      let aaf = aa |> A.map (fun x ->
        let lp = largest_prime_factor x in (lp, x))
      in
      A.sort compare aaf;
      (* print_array @@ A.map fst aaf; *)
      (* print_array @@ A.map snd aaf; *)
      let (aap, aas) = A.split aaf in

      let rec loop s =
        printf "loop2 %d " s;
        if s >= A.len aaf then ()
        else (
          let p = aap.(s) in
          match findi_opt (fun p' -> p' > p) s aap with
          | Some e ->
            (* printf "%d:" e; print_array aas; *)
            sieve_in_place s e 1000001 aas;
            loop e
          | None ->
            sieve_in_place s (A.len aas) 1000001 aas;
            ()
        ); puts ""
      in
      loop 0;
      aas |> A.filter_map (fun x -> if x = 0 then None else Some x)
    )
  in

  let (rs, ss) = isolate al in
  let aa0 = Ss.to_array rs in

  let (aa1, aar) = sieve_le_1000 aa0 in
  let aa2 = sieve_gt_1000 aar in
  (* print_array aa1; *)
  (* print_array aa2; *)
  let sieved = Ss.of_array @@ A.append aa1 aa2 in
  let result = Ss.diff sieved ss in
  (* print_array @@ Ss.to_array result; *)
  puti @@ Ss.size result
;;