let (a, b) = Scanf.sscanf (read_line ()) "%d %f" @@ fun a b -> (a, b)

let () = Printf.printf "%d\n" @@ (a * int_of_float (b *. 100.)) / 100


Scanf.scanf "%d %f" (fun a b ->
    Printf.printf "%d\n" @@ a * int_of_float (floor (b *. 100. +. 0.5)) / 100
)

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

Score : 300 points

Problem Statement

Compute A \times B, truncate its fractional part, and print the result as an integer.

Constraints

0 \leq A \leq 10^{15}

0 \leq B < 10

A is an integer.

B is a number with two digits after the decimal point.

Input

Input is given from Standard Input in the following format:

A B

Output

Print the answer as an integer.

Sample Input 1

198 1.10

Sample Output 1

217

We have 198 \times 1.10 = 217.8. After truncating the fractional part, we have the answer: 217.

Sample Input 2

1 0.01

Sample Output 2

0

Sample Input 3

1000000000000000 9.99

Sample Output 3

9990000000000000

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.


let (a, b) = Scanf.sscanf (read_line ()) "%d %f" @@ fun a b -> (a, b)

let () = Printf.printf "%d\n" @@ int_of_float @@ floor (float a *. b)


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 = List.range n `To m
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 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,k) = scan "%d %d" Tuple2.make
let arr = scan_array ~sep:' ' Int.of_string

let visited = Array.make n false

let rec to_num from to_ n =
  if from = to_ then n
  else to_num arr.(pred from) to_ @@ succ n

let rec loop i =
  if visited.(pred i) then i
  else
    (visited.(pred i) <- true;
     loop arr.(pred i))

let rec route n i =
  if n = 0 then i
  else route (pred n) arr.(pred i)

let () =
  let loop_n = loop 1 in
  let loop_num = to_num arr.(pred loop_n) loop_n 1 in
  let to_loop = to_num 1 loop_n 0 in
  Printf.printf "%d\n"
    (if k < to_loop then route k 1
     else route ((k-to_loop) mod loop_num) loop_n)

Score: 400 points

Problem Statement

The Kingdom of Takahashi has N towns, numbered 1 through N.

There is one teleporter in each town. The teleporter in Town i (1 \leq i \leq N) sends you to Town A_i.

Takahashi, the king, loves the positive integer K. The selfish king wonders what town he will be in if he starts at Town 1 and uses a teleporter exactly K times from there.

Help the king by writing a program that answers this question.

Constraints

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

1 \leq A_i \leq N

1 \leq K \leq 10^{18}

Input

Input is given from Standard Input in the following format:

N K
A_1 A_2 \dots A_N

Output

Print the integer representing the town the king will be in if he starts at Town 1 and uses a teleporter exactly K times from there.

Sample Input 1

4 5
3 2 4 1

Sample Output 1

4

If we start at Town 1 and use the teleporter 5 times, our travel will be as follows: 1 \to 3 \to 4 \to 1 \to 3 \to 4.

Sample Input 2

6 727202214173249351
6 5 2 5 3 2

Sample Output 2

2


let split_string ?(pattern=" ") = Str.split @@ Str.regexp pattern
let (n, j) = Scanf.sscanf (read_line ())"%d %d" @@ fun n j -> (n, j)
let a = Array.of_list @@ List.map int_of_string @@ split_string @@ read_line ()
let v = Array.make n 0

let rec tp acc i =
  if v.(i) = 1 then (i, List.rev acc)
  else (v.(i) <- 1; tp (i :: acc) (a.(i) - 1))
let tp = tp [] 0

let rec loop (p, acc) i =
  if i = 0 then print_int (List.hd acc + 1)
  else if p = (List.hd acc) then print_int ((List.nth acc (i mod (List.length acc))) + 1)
  else loop (p, (List.tl acc)) (i - 1)

let () = loop tp j


let () =
  Scanf.scanf "%d %d" @@ fun n k ->
  let a = Array.init (n+1) (fun i -> if i = 0 then 1 else Scanf.scanf " %d" Fun.id) in

  let lv = Array.make (n+1) (-1) in
  let rec loop c i =
    if c = k then i
    else if lv.(i) >= 0 then
      let c' = lv.(i) in
      if (k - c) mod (c - c') = 0 then i
      else loop (c+1) a.(i)
    else begin
      lv.(i) <- c;
      loop (c+1) a.(i)
    end in

  Printf.printf "%d\n" (loop 0 1)


let () =
  let n, k = Scanf.scanf "%d %d\n" @@ fun a b -> a, b in
  let arr = Array.init n @@ fun _ -> Scanf.scanf "%d " @@ fun d -> d in
  let alen = Array.length arr in
  let rec f x i len =
    if x = 1 || i = len then [] else x :: f arr.(x-1) (i+1) len in
  let rec g x k = if k = 0 then x else g arr.(x-1) (k-1) in
  let brr = Array.of_list (f arr.(0) 1 alen) in
  let blen = Array.length brr in
  print_int (if alen <> blen then brr.(k mod blen) else g brr.(blen-1) (k-alen))


let () =
  let n, k = Scanf.scanf "%d %d\n" @@ fun a b -> a, b in
  let arr = Array.init n @@ fun _ -> Scanf.scanf "%d " @@ fun d -> d in
  let rec f i x = if x = 1 then i else f (i+1) arr.(x-1) in
  let i = f 1 arr.(0) in
  let next = ref arr.(0) in
  for i = 0 to (k mod i) do
    next := arr.(!next - 1)
  done;
  print_int (!next + 1)


let () = Scanf.scanf "%d %d\n" @@ fun n k ->
  let tele = Array.make_matrix n 62 0 in
  for i = 0 to n - 1 do
    Scanf.scanf "%d " @@ fun a ->
      tele.(i).(0) <- a - 1
  done;
  for j = 0 to 60 do
    for i = 0 to n - 1 do
      tele.(i).(j + 1) <- tele.(tele.(i).(j)).(j)
    done
  done;
  Printf.printf "%d\n" @@
  succ @@
  List.fold_left (fun c i ->
    if k land (1 lsl i) = 0
    then c
    else tele.(c).(i)) 0 @@
  List.init 62 Fun.id


Scanf.scanf "%d %d %d %d" (fun a b c d ->
  let rec f a c =
    let c = c - b in
    if c <= 0 then "Yes"
    else g a c
  and g a c =
    let a = a - d in
    if a <= 0 then "No"
    else f a c
  in print_endline (f a c)
)

Score : 200 points

Problem Statement

Takahashi and Aoki will have a battle using their monsters.

The health and strength of Takahashi's monster are A and B, respectively, and those of Aoki's monster are C and D, respectively.

The two monsters will take turns attacking, in the order Takahashi's, Aoki's, Takahashi's, Aoki's, ...
Here, an attack decreases the opponent's health by the value equal to the attacker's strength.
The monsters keep attacking until the health of one monster becomes 0 or below. The person with the monster whose health becomes 0 or below loses, and the other person wins.

If Takahashi will win, print Yes; if he will lose, print No.

Constraints

1 \leq A,B,C,D \leq 100

All values in input are integers.

Input

Input is given from Standard Input in the following format:

A B C D

Output

If Takahashi will win, print Yes; if he will lose, print No.

Sample Input 1

10 9 10 10

Sample Output 1

No

First, Takahashi's monster attacks Aoki's monster, whose health is now 10-9=1.

Next, Aoki's monster attacks Takahashi's monster, whose health is now 10-10=0.

Takahashi's monster is the first to have 0 or less health, so Takahashi loses.

Sample Input 2

46 4 40 5

Sample Output 2

Yes


let a, b, c, d = Scanf.sscanf (read_line ()) "%d %d %d %d" @@ fun a b c d -> (a, b, c, d)

let rec loop t a c =
  if t then
    if b >= c then "Yes" else loop false a (c - b)
  else
    if d >= a then "No" else loop true (a - d) c

let () = print_endline @@ loop true a c


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 = List.range n `To m
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 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 (a,b,c,d) = scan "%d %d %d %d" Tuple4.make

exception Found of bool

let () =
  try ListL.iter (0++100) ~f:(fun i ->
      let n = a - d*i in
      let m = c - b*i in
      if n <= 0 || m <= 0 then
        if n > 0 then raise @@ Found true
        else if n <= 0 && m <= 0 then raise @@ Found true
        else raise @@ Found false
    ) with | Found t ->
    Printf.printf "%s\n" (if t then "Yes" else "No")


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 = List.range n `To m
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 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 (a,b,c,d) = scan "%d %d %d %d" Tuple4.make

exception Found of bool

let () =
  try ListL.iter (0++100) ~f:(fun i ->
      let n = a - d*i in
      let m = b - b*i in
      if n <= 0 || m <= 0 then
        if n > 0 then raise @@ Found true
        else if n <= 0 && m <= 0 then raise @@ Found true
        else raise @@ Found false
    ) with | Found t ->
    Printf.printf "%s\n" (if t then "Yes" else "No")


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 (a,b,c,d) = scan "%d %d %d %d" Tuple4.make

let () =
  (if (c+pred b)/b <= (a+pred d)/d then "Yes" else "No")
  |> Printf.printf "%s\n"


let a,b,c,d = Scanf.scanf "%d %d %d %d\n" @@ fun a b c d -> a, b, c, d
let rec f a b c d t =
  if a <= 0 then false else if c <= 0 then true
  else if t then f a b (c-b) d false else f (a-d) b c d true
let ans = if (f a b c d true) then "Yes" else "No"
let () = print_endline ans


let moves attack defence =
  (defence / attack) + (if defence mod attack == 0 then 0 else 1)

let () =
  let (h1, s1, h2, s2) = Scanf.scanf "%d %d %d %d" (fun a b c d -> a, b, c, d) in
  let s1 = moves s1 h2 in
  let s2 = moves s2 h1 in
  print_string (if s1 <= s2 then "Yes" else "No")


let moves attack defence =
  defence / attack + (if defence mod attack == 0 then 0 else 1)

let () =
  let a = read_int() in
  let b = read_int() in
  let c = read_int() in
  let d = read_int() in
  let s1 = moves (min c d) (max a b) in
  let s2 = moves (min a b) (max c d) in
  print_string (if s1 <= s2 then "Yes" else "No")


open Printf
open Scanf

let solve a b c d =
  let f x y = (x + y - 1) / y in
  if f a d >= f c b then "Yes" else "No"

let () =
  scanf "%d %d %d %d " solve |> printf "%s\n"


let () = Scanf.scanf "%d %d %d %d" @@ fun a b c d ->
  print_endline @@
  if (c + b - 1) / b <= (a + d - 1) / d
  then "Yes"
  else "No"


Scanf.scanf "%d %d %d %d" (fun a b c d ->
    let rec loop taka aoki turn =
        if turn then (
            let aoki = aoki - b in
            if aoki > 0 then loop taka aoki false else "Yes"
        ) else (
            let taka = taka - d in
            if taka > 0 then loop taka aoki true else "No"
        )
    in
    print_endline @@ loop a c true
)


let s = read_line()
let a = Array.make 2019 0

let rec f i d n ans =
  if i = -1 then ans
  else
    let j = int_of_char s.[i] - int_of_char '0' in
    let n = (j * d + n) mod 2019 in
    let an = a.(n) in
    a.(n) <- an + 1;
    f (i - 1) (10 * d mod 2019) n (ans + an)

let () =
  a.(0) <- 1;
  let l = String.length s - 1 in
  let ans = f l 1 0 0 in
  Printf.printf "%d\n" ans

Score : 400 points

Problem Statement

Given is a string S consisting of digits from 1 through 9.

Find the number of pairs of integers (i,j) (1 ≤ i ≤ j ≤ |S|) that satisfy the following condition:

Condition: In base ten, the i-th through j-th characters of S form an integer that is a multiple of 2019.

Constraints

1 ≤ |S| ≤ 200000

S is a string consisting of digits from 1 through 9.

Input

Input is given from Standard Input in the following format:

S

Output

Print the number of pairs of integers (i,j) (1 ≤ i ≤ j ≤ |S|) that satisfy the condition.

Sample Input 1

1817181712114

Sample Output 1

3

Three pairs - (1,5), (5,9), and (9,13) - satisfy the condition.

Sample Input 2

14282668646

Sample Output 2

2

Sample Input 3

2119

Sample Output 3

0

No pairs satisfy the condition.


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 = List.range n `To m
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 = 2019
  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 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 s = String.to_list @@ scan "%s" id
let arr = Array.make (List.length s) 0

let () =
  List.fold_lefti (fun prev i c ->
      let open ModOp in
      let n = prev + pow 10 i * atoi c in
      arr.(i) <- n mod 2019; n)
    0 (List.rev s) |> ignore;
  let h = Hashtbl.create (Array.length arr) in
  Hashtbl.add h 0 1;
  ArrayL.iter arr ~f:(fun i -> Hashtbl.modify_def 0 i succ h);
  Hashtbl.map (fun _ i -> i*(i-1)/2) h |> Hashtbl.to_list
  |> List.map Tuple2.second
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 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 s = String.to_list @@ scan "%s" id
let arr = Array.make (List.length s) 0

let () =
  List.fold_lefti (fun prev i c ->
      let n = prev + Int.pow 10 i * atoi c in
      arr.(i) <- n mod 2019; n)
    0 (List.rev s) |> ignore;
  let h = Hashtbl.create (Array.length arr) in
  Hashtbl.add h 0 1;
  ArrayL.iter arr ~f:(fun i -> Hashtbl.modify_def 0 i succ h);
  Hashtbl.map (fun _ i -> i*(i-1)/2) h |> Hashtbl.to_list
  |> List.map Tuple2.second
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id

let map_predi ~init ~f =
  let rec aux n pred = function
    | [] -> []
    | x::rest ->
      let cur = f n pred x in
      cur :: aux (succ n) cur rest
  in aux 0 init

let rec pow_mod n m =
  if m = 0 then 1
  else if m mod 2 = 0 then
    pow_mod (n*n mod 2019) (m/2)
  else
    n * (pow_mod (n*n mod 2019) ((pred m)/ 2)) mod 2019

let count_list l =
  let h = Hashtbl.create 0 in
  ListL.iter l ~f:(fun i ->
      Hashtbl.replace h i @@ succ @@ Hashtbl.find_default h i 0);
  Hashtbl.to_list h

let () =
  let l =
    0::(String.to_list s
        |> List.rev
        |> map_predi ~init:0 ~f:(fun i pred c ->
            let ( * ) n m = n * m mod 2019 in
            let (+) n m = (n + m) mod 2019 in
            let n = Char.code c - Char.code '0' in
            ((n*pow_mod 10 i) + pred))) in
  count_list l
  |> ListL.map ~f:(fun (_, m) -> m*(m-1)/2)
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id

let map_predi ~init ~f =
  let rec aux n pred = function
    | [] -> []
    | x::rest ->
      let cur = f n pred x in
      cur :: aux (succ n) cur rest
  in aux 0 init

let rec pow_mod n m =
  if m = 0 then 1
  else if m mod 2 = 0 then
    pow_mod (n*n mod 2019) (m/2)
  else
    n * (pow_mod (n*n mod 2019) ((pred m)/ 2)) mod 2019

let () =
  let l =
    0::(String.to_list s
        |> List.rev
        |> map_predi ~init:0 ~f:(fun i pred c ->
            let ( * ) n m = n * m mod 2019 in
            let (+) n m = (n + m) mod 2019 in
            let n = Char.code c - Char.code '0' in
            ((n*pow_mod 10 i) + pred))) in
  let h = Hashtbl.create 0 in
  ListL.iter l ~f:(fun i ->
      Hashtbl.add h i @@ succ @@ Hashtbl.find_default h i 0);
  Hashtbl.to_list h
  |> ListL.map ~f:(fun (_, m) -> m*(m-1)/2)
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id

let map_predi ~init ~f =
  let rec aux n pred = function
    | [] -> []
    | x::rest ->
      let cur = f n pred x in
      cur :: aux (succ n) cur rest
  in aux 0 init

let rec pow_mod n m=
  if m = 0 then 1
  else
    (n * pow_mod n (pred m)) mod 2019

let () =
  let l =
    0::(String.to_list s
        |> List.rev
        |> map_predi ~init:0 ~f:(fun i pred c ->
            let ( * ) n m = n * m mod 2019 in
            let (+) n m = (n + m) mod 2019 in
            let n = Char.code c - Char.code '0' in
            ((n*pow_mod 10 i) + pred))) in
  let h = Hashtbl.create 0 in
  ListL.iter l ~f:(fun i ->
      Hashtbl.add h i @@ succ @@ Hashtbl.find_default h i 0);
  Hashtbl.to_list h
  |> ListL.map ~f:(fun (_, m) -> m*(m-1)/2)
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id

let map_predi ~init ~f =
  let rec aux n pred = function
    | [] -> []
    | x::rest ->
      let cur = f n pred x in
      cur :: aux (succ n) cur rest
  in aux 0 init

let () =
  let l = 0::(String.to_list s
              |> List.rev
              |> map_predi ~init:0 ~f:(fun i pred c ->
                  let ( * ) = Int64.( * ) in
                  let n = Int64.of_int @@ Char.code c - Char.code '0' in
                  ((Int64.to_int (Int64.modulo (n * Int64.pow 10L
                                                  (Int64.of_int i)) 2019L))
                   + pred) mod 2019)) in
  let h = Hashtbl.create 0 in
  ListL.iter l ~f:(fun i ->
      Hashtbl.add h i @@ succ @@ Hashtbl.find_default h i 0);
  Hashtbl.to_list h
  |> ListL.map ~f:(fun (_, m) -> m*(m-1)/2)
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id

let map_predi ~init ~f =
  let rec aux n pred = function
    | [] -> []
    | x::rest ->
      let cur = f n pred x in
      cur :: aux (succ n) cur rest
  in aux 0 init

let () =
  let l = 0::(String.to_list s
              |> List.rev
              |> map_predi ~init:0 ~f:(fun i pred c ->
                  (((Char.code c - Char.code '0') * Int.pow 10 i) mod 2019
                   + pred) mod 2019)) in
  let h = Hashtbl.create 0 in
  ListL.iter l ~f:(fun i ->
      Hashtbl.add h i @@ succ @@ Hashtbl.find_default h i 0);
  Hashtbl.to_list h
  |> ListL.map ~f:(fun (_, m) -> m*(m-1)/2)
  |> List.sum
  |> Printf.printf "%d\n"


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 = List.range n `To m
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 []

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 rec powerset e =
  match Enum.get e with
  | None -> Enum.singleton @@ Enum.empty ()
  | Some v ->
    let f = powerset e in
    let g = Enum.clone f in
    EnumL.map f ~f:(fun x -> let y = Enum.clone x in push y v; y)
    |>  Enum.append g

let permutations l =
  let rec aux l =
    let rec interleave x = function
      | [] -> [[x]]
      | (hd::tl) as lst ->
        (x::lst) ::
        (ListL.map ~f:(List.cons hd)  @@ interleave x tl)
    in
    match l with
    | [] -> [[]]
    | hd::tl -> List.concat @@ List.map (interleave hd) @@ aux tl in
  let l = List.sort (List.compare Int.compare) @@ aux @@ List.of_enum l in
  List.enum % ListL.map ~f:List.enum @@ 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 s = scan "%s" id
let hs = Hashtbl.create 0;;

ListL.iter (1++^100) ~f:(fun i ->
    let s = String.of_int @@ 2019*i in
    let c = String.get s 0 in
    Hashtbl.add hs c
      (s :: (Hashtbl.find_default hs c [])))

let () =
  ListL.map (0++^String.length s) ~f:(fun i ->
      let c = String.get s i  in
      match Hashtbl.find_option hs c with
      | None -> 0
      | Some ss ->
        ListL.map ss ~f:(fun ss ->
            if i + String.length ss <= String.length s &&
               String.sub s i (String.length ss) = ss then 1
            else 0)
        |> List.sum)
  |> List.sum
  |> Printf.printf "%d\n"


let id x = x

let s = Scanf.scanf "%s\n" id

let s_len = String.length s

let () =
  let ans = ref 0 in
  for i = 0 to s_len - 5 do
    for j = 4 to s_len - i do
      let t = int_of_string (String.sub s i j) in
      ans := !ans + if t mod 2019 = 0 then 1 else 0
    done
  done;
  print_int !ans


let m = 2019
let ( +^ ) x y = (x + y) mod m
let ( *^ ) x y = (x * y) mod m
let inv10 = 202

let () =
  let s = read_line () in
  let n = String.length s in
  let a = Array.make 2019 0 in
  let inv = ref 1 in
  let acc = ref 0 in
  a.(0) <- 1;
  for i = 0 to n - 1 do
    inv := inv10 *^ !inv;
    acc := !acc +^ (Char.code s.[i] - Char.code '0') *^ !inv;
    a.(!acc) <- 1 + a.(!acc)
  done;
  Printf.printf "%d\n" @@
  Array.fold_right (fun a -> ( + ) @@ a * (a - 1) / 2) a 0


open Batteries
(* 前からst文字を切り抜く *)
let slice st str = String.init (String.length str - st) (fun a -> String.get str (a+st))
(* 文字列をcharのarrayにする *)
let explode s = List.init (String.length s) (String.get s) |> Array.of_list
let s = read_line () |> explode
let sl = Array.length s

let get_start_to_end i j =
  String.init (j - i + 1) @@ fun a -> s.(a + i)
let t = Big_int.big_int_of_int 2019

let rec loop1 i ans=
  let rec loop2 j ans1=
    if j >= sl then ans1 else
      (
        if Big_int.eq_big_int ( Big_int.mod_big_int ((get_start_to_end i j) |> Big_int.big_int_of_string) t) Big_int.zero_big_int
        then loop2 (j+i+1) (ans1+1)
        else loop2 (j+1) ans1
      )
  in if i >= sl-4 then ans else (loop1 (i+1) (ans+(loop2 (i+1) 0)))

let _ = loop1 0 0 |> Printf.printf "%d\n"


open Batteries
(* open Big_int *)
(* 前からst文字を切り抜く *)
let slice st str = String.init (String.length str - st) (fun a -> String.get str (a+st))
(* 文字列をcharのlistにする *)
let explode s = List.init (String.length s) (String.get s)
let s = read_line () |> explode
let sl = List.length s
let dp = Array.init (sl+1) @@ fun a -> ""

let rec loop old lst i =
  match lst with
  | [] -> dp.(i) <- old
  | first :: rest -> dp.(i) <- old; loop (old ^ (Char.escaped first)) rest (i+1)

let _ = loop "" s 0
let t = Big_int.big_int_of_int 2019
let rec loop1 i =
  let rec loop2 j =
    if j > sl then 0 else
    (
      if Big_int.eq_big_int (Big_int.mod_big_int (slice (String.length dp.(i)) dp.(j) |> Big_int.big_int_of_string) t) Big_int.zero_big_int then 1 + loop2 (j+2) else loop2 (j+1)
    )
  in if i >= sl-3 then 0 else (loop2 (i+1) + loop1 (i+1))

let _ = loop1 0 |> Printf.printf "%d\n"


let m = 2019
let ( +^ ) x y = (x + y) mod m
let ( *^ ) x y = (x * y) mod m
let inv10 = 202
let rec power ( * ) e m n =
  if n <= 0 then e
  else power ( * ) (if n land 1 = 0 then e else m * e) (m * m) (n lsr 1)

let () =
  let s = read_line () in
  let n = String.length s in
  let acc = Array.make (n + 1) 0 in
  for i = 0 to n - 1 do
    acc.(i + 1) <- 10 *^ acc.(i) +^ (Char.code s.[i] - Char.code '0')
  done;
  let a = Array.make 2019 0 in
  Array.iteri (fun i n ->
    let j = power ( *^ ) n inv10 i in
    a.(j) <- 1 + a.(j)) acc;
  Printf.printf "%d\n" @@
  Array.fold_right (fun a -> ( + ) @@ a * (a - 1) / 2) a 0


open Batteries
(* open Big_int *)
(* 前からst文字を切り抜く *)
let slice st str = String.init (String.length str - st) (fun a -> String.get str (a+st))
(* 文字列をcharのlistにする *)
let explode s = List.init (String.length s) (String.get s)
let s = read_line () |> explode
let sl = List.length s
let dp = Array.init (sl+1) @@ fun a -> ""

let rec loop old lst i =
  match lst with
  | [] -> dp.(i) <- old
  | first :: rest -> dp.(i) <- old; loop (old ^ (Char.escaped first)) rest (i+1)

let _ = loop "" s 0
let t = Big_int.big_int_of_int 2019
let rec loop1 i =
  let rec loop2 j =
    if j > sl then 0 else
    (
      if Big_int.mod_big_int (slice (String.length dp.(i)) dp.(j) |> Big_int.big_int_of_string) t  = Big_int.zero_big_int then 1 + loop2 (j+2) else loop2 (j+1)
    )
  in if i >= sl-3 then 0 else (loop2 (i+1) + loop1 (i+1))

let _ = loop1 0 |> Printf.printf "%d\n"


open Batteries
(* 前からst文字を切り抜く *)
let slice st str = String.init (String.length str - st) (fun a -> String.get str (a+st))
(* 文字列をcharのlistにする *)
let explode s = List.init (String.length s) (String.get s)
let s = read_line () |> explode
let sl = List.length s
let dp = Array.init (sl+1) @@ fun a -> ""

let rec loop old lst i =
  match lst with
  | [] -> dp.(i) <- old
  | first :: rest -> dp.(i) <- old; loop (old ^ (Char.escaped first)) rest (i+1)

let _ = loop "" s 0

let rec loop1 i =
  let rec loop2 j =
    if j > sl then 0 else
    (
      if (slice (String.length dp.(i)) dp.(j) |> int_of_string) mod 2019 = 0 then 1 + loop2 (j+2) else loop2 (j+1)
    )
  in if i >= sl-3 then 0 else (loop2 (i+1) + loop1 (i+1))

let _ = loop1 0 |> Printf.printf "%d\n"


Scanf.scanf "%s" (fun s ->
    let n = String.length s in
    let arr = Array.make 2019 0 in
    arr.(0) <- 1;
    let rec loop i cur ten =
        if i >= 0 then (
            let cur = (cur + ten * ( int_of_char s.[i] - 48)) mod 2019 in
            arr.(cur) <- arr.(cur) + 1;
            loop (i - 1) cur ((ten * 10) mod 2019)
        )
    in
    loop (n - 1) 0 1;
    Array.fold_left (fun acc v -> acc + v * (v - 1) / 2) 0 arr |> Printf.printf "%d\n"
)


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let used = Array2.create int8_signed c_layout n (money_inf+1)
let () = Array2.fill used 0
let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = int * Dijk.t Array.t
    let zero = (0L, 0, 0)
    let to_tup dist (v,money) = (dist, v, money)
    let of_tup (dist,v,money) = (dist, (v, money))
    let min_elt (last, h) = if last = 0 then None
        else Some (of_tup h.(1))
    let remove_min (last, h) = if last = 0 then (last, h) else begin
        h.(1) <- h.(last);
        let last = last - 1 in
        let rec loop i = if 2 * i > last then () (* 子なし *)
            else if 2 * i = last then (* 子1人 *)
                if Dijk.compare h.(2 * i) h.(i) >= 0 then () else Array.swap h (2 * i) i
            else
                let j = if Dijk.compare h.(2 * i + 1) h.(2 * i) >= 0
                    then 2 * i
                    else 2 * i + 1
                in
                if Dijk.compare h.(j) h.(i) >= 0 then ()
                else (Array.swap h j i; loop j)
        in
        loop 1;
        (last, h)
        end
    let add (last, h) dist x =
        let last = last + 1 in
        let h = if last >= Array.length h
            then begin
                let h2 = Array.create ~len:(2 * Array.length h) zero in
                Array.blit h 0 h2 0 last;
                h2
            end else h
        in
        let rec loop i = if i = 1 then ()
            else if Dijk.compare h.(i) h.(i / 2) >= 0 then ()
            else (Array.swap h i (i / 2); loop (i / 2))
        in
        h.(last) <- to_tup dist x;
        loop last;
        (last, h)
    let singleton dist x = (1, Array.create ~len:100000 (to_tup dist x))
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if used.{v, money} = 1 then loop mins else begin
        used.{v, money} <- 1;
        res.{v, money} <- dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist < res.{v,money}) && used.{v,money} = 0
            then (res.{v,money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist < res.{v,money}) && used.{v,money} = 0
            then (res.{v,money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done

Score : 500 points

Problem Statement

There are N cities numbered 1 to N, connected by M railroads.

You are now at City 1, with 10^{100} gold coins and S silver coins in your pocket.

The i-th railroad connects City U_i and City V_i bidirectionally, and a one-way trip costs A_i silver coins and takes B_i minutes.
You cannot use gold coins to pay the fare.

There is an exchange counter in each city. At the exchange counter in City i, you can get C_i silver coins for 1 gold coin.
The transaction takes D_i minutes for each gold coin you give.
You can exchange any number of gold coins at each exchange counter.

For each t=2, ..., N, find the minimum time needed to travel from City 1 to City t. You can ignore the time spent waiting for trains.

Constraints

2 \leq N \leq 50

N-1 \leq M \leq 100

0 \leq S \leq 10^9

1 \leq A_i \leq 50

1 \leq B_i,C_i,D_i \leq 10^9

1 \leq U_i < V_i \leq N

There is no pair i, j(i \neq j) such that (U_i,V_i)=(U_j,V_j).

Each city t=2,...,N can be reached from City 1 with some number of railroads.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M S
U_1 V_1 A_1 B_1
:
U_M V_M A_M B_M
C_1 D_1
:
C_N D_N

Output

For each t=2, ..., N in this order, print a line containing the minimum time needed to travel from City 1 to City t.

Sample Input 1

3 2 1
1 2 1 2
1 3 2 4
1 11
1 2
2 5

Sample Output 1

2
14

The railway network in this input is shown in the figure below.

In this figure, each city is labeled as follows:

The first line: the ID number i of the city (i for City i)

The second line: C_i / D_i

Similarly, each railroad is labeled as follows:

The first line: the ID number i of the railroad (i for the i-th railroad in input)

The second line: A_i / B_i

You can travel from City 1 to City 2 in 2 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 2 minutes.

You can travel from City 1 to City 3 in 14 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 2 minutes.

At the exchange counter in City 2, exchange 3 gold coins for 3 silver coins in 6 minutes.

Use the 1-st railroad to move from City 2 to City 1 in 2 minutes.

Use the 2-nd railroad to move from City 1 to City 3 in 4 minutes.

Sample Input 2

4 4 1
1 2 1 5
1 3 4 4
2 4 2 2
3 4 1 1
3 1
3 1
5 2
6 4

Sample Output 2

5
5
7

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 4 in 7 minutes, as follows:

At the exchange counter in City 1, exchange 2 gold coins for 6 silver coins in 2 minutes.

Use the 2-nd railroad to move from City 1 to City 3 in 4 minutes.

Use the 4-th railroad to move from City 3 to City 4 in 1 minutes.

Sample Input 3

6 5 1
1 2 1 1
1 3 2 1
2 4 5 1
3 5 11 1
1 6 50 1
1 10000
1 3000
1 700
1 100
1 1
100 1

Sample Output 3

1
9003
14606
16510
16576

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 6 in 16576 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.

At the exchange counter in City 2, exchange 3 gold coins for 3 silver coins in 9000 minutes.

Use the 1-st railroad to move from City 2 to City 1 in 1 minute.

Use the 2-nd railroad to move from City 1 to City 3 in 1 minute.

At the exchange counter in City 3, exchange 8 gold coins for 8 silver coins in 5600 minutes.

Use the 2-nd railroad to move from City 3 to City 1 in 1 minute.

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.

Use the 3-rd railroad to move from City 2 to City 4 in 1 minute.

At the exchange counter in City 4, exchange 19 gold coins for 19 silver coins in 1900 minutes.

Use the 3-rd railroad to move from City 4 to City 2 in 1 minute.

Use the 1-st railroad to move from City 2 to City 1 in 1 minute.

Use the 2-nd railroad to move from City 1 to City 3 in 1 minute.

Use the 4-th railroad to move from City 3 to City 5 in 1 minute.

At the exchange counter in City 5, exchange 63 gold coins for 63 silver coins in 63 minutes.

Use the 4-th railroad to move from City 5 to City 3 in 1 minute.

Use the 2-nd railroad to move from City 3 to City 1 in 1 minute.

Use the 5-th railroad to move from City 1 to City 6 in 1 minute.

Sample Input 4

4 6 1000000000
1 2 50 1
1 3 50 5
1 4 50 7
2 3 50 2
2 4 50 4
3 4 50 3
10 2
4 4
5 5
7 7

Sample Output 4

1
3
5

The railway network in this input is shown in the figure below:

Sample Input 5

2 1 0
1 2 1 1
1 1000000000
1 1

Sample Output 5

1000000001

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 2 in 1000000001 minutes, as follows:

At the exchange counter in City 1, exchange 1 gold coin for 1 silver coin in 1000000000 minutes.

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let used = Array2.create int8_signed c_layout n (money_inf+1)
let () = Array2.fill used 0
let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = int * Dijk.t Array.t
    let zero = (0L, 0, 0)
    let to_tup dist (v,money) = (dist, v, money)
    let of_tup (dist,v,money) = (dist, (v, money))
    let min_elt (last, h) = if last = 0 then None
        else Some (of_tup h.(1))
    let remove_min (last, h) = if last = 0 then (last, h) else begin
        h.(1) <- h.(last);
        let last = last - 1 in
        let rec loop i = if 2 * i > last then () (* 子なし *)
            else if 2 * i = last then (* 子1人 *)
                if Dijk.compare h.(2 * i) h.(i) >= 0 then () else Array.swap h (2 * i) i
            else
                let j = if Dijk.compare h.(2 * i + 1) h.(2 * i) >= 0
                    then 2 * i
                    else 2 * i + 1
                in
                if Dijk.compare h.(j) h.(i) >= 0 then ()
                else (Array.swap h j i; loop j)
        in
        loop 1;
        (last, h)
        end
    let add (last, h) dist x =
        let last = last + 1 in
        let h = if last >= Array.length h
            then begin
                let h2 = Array.create ~len:(2 * Array.length h) zero in
                Array.blit h 0 h2 0 last;
                h2
            end else h
        in
        let rec loop i = if i = 1 then ()
            else if Dijk.compare h.(i) h.(i / 2) >= 0 then ()
            else (Array.swap h i (i / 2); loop (i / 2))
        in
        h.(last) <- to_tup dist x;
        loop last;
        (last, h)
    let singleton dist x = (1, Array.create ~len:100000 (to_tup dist x))
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if used.{v, money} = 1 then loop mins else begin
        used.{v, money} <- 1;
        res.{v, money} <- dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && used.{v,money} = 0
            then H.add mins dist (v, money)
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && used.{v,money} = 0
            then H.add mins dist (v, money)
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = int * Dijk.t Array.t
    let zero = (0L, 0, 0)
    let to_tup dist (v,money) = (dist, v, money)
    let of_tup (dist,v,money) = (dist, (v, money))
    let min_elt (last, h) = if last = 0 then None
        else Some (of_tup h.(1))
    let remove_min (last, h) = if last = 0 then (last, h) else begin
        h.(1) <- h.(last);
        let last = last - 1 in
        let rec loop i = if 2 * i > last then () (* 子なし *)
            else if 2 * i = last then (* 子1人 *)
                if Dijk.compare h.(2 * i) h.(i) >= 0 then () else Array.swap h (2 * i) i
            else
                let j = if Dijk.compare h.(2 * i + 1) h.(2 * i) >= 0
                    then 2 * i
                    else 2 * i + 1
                in
                if Dijk.compare h.(j) h.(i) >= 0 then ()
                else (Array.swap h j i; loop j)
        in
        loop 1;
        (last, h)
        end
    let add (last, h) dist x =
        let last = last + 1 in
        let h = if last >= Array.length h
            then begin
                let h2 = Array.create ~len:(2 * Array.length h) zero in
                Array.blit h 0 h2 0 last;
                h2
            end else h
        in
        let rec loop i = if i = 1 then ()
            else if Dijk.compare h.(i) h.(i / 2) >= 0 then ()
            else (Array.swap h i (i / 2); loop (i / 2))
        in
        h.(last) <- to_tup dist x;
        loop last;
        (last, h)
    let singleton dist x = (1, Array.create ~len:100000 (to_tup dist x))
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if Int64.(dist > res.{v, money}) then loop mins else begin
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist < res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist < res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let used = Array2.create int8_signed c_layout n (money_inf+1)
let () = Array2.fill used 0
let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = int * Dijk.t Array.t
    let zero = (0L, 0, 0)
    let to_tup dist (v,money) = (dist, v, money)
    let of_tup (dist,v,money) = (dist, (v, money))
    let min_elt (last, h) = if last = 0 then None
        else Some (of_tup h.(1))
    let remove_min (last, h) = if last = 0 then (last, h) else begin
        h.(1) <- h.(last);
        let last = last - 1 in
        let rec loop i = if 2 * i > last then () (* 子なし *)
            else if 2 * i = last then (* 子1人 *)
                if Dijk.compare h.(2 * i) h.(i) >= 0 then () else Array.swap h (2 * i) i
            else
                let j = if Dijk.compare h.(2 * i + 1) h.(2 * i) >= 0
                    then 2 * i
                    else 2 * i + 1
                in
                if Dijk.compare h.(j) h.(i) >= 0 then ()
                else (Array.swap h j i; loop j)
        in
        loop 1;
        (last, h)
        end
    let add (last, h) dist x =
        let last = last + 1 in
        let h = if last >= Array.length h
            then begin
                let h2 = Array.create ~len:(2 * Array.length h) zero in
                Array.blit h 0 h2 0 last;
                h2
            end else h
        in
        let rec loop i = if i = 1 then ()
            else if Dijk.compare h.(i) h.(i / 2) >= 0 then ()
            else (Array.swap h i (i / 2); loop (i / 2))
        in
        h.(last) <- to_tup dist x;
        loop last;
        (last, h)
    let singleton dist x = (1, Array.create ~len:100000 (to_tup dist x))
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if used.{v, money} = 1 then loop mins else begin
        used.{v, money} <- 1;
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = int * Dijk.t Array.t
    let zero = (0L, 0, 0)
    let to_tup dist (v,money) = (dist, v, money)
    let of_tup (dist,v,money) = (dist, (v, money))
    let min_elt (last, h) = if last = 0 then None
        else Some (of_tup h.(1))
    let remove_min (last, h) = if last = 0 then (last, h) else begin
        h.(1) <- h.(last);
        let last = last - 1 in
        let rec loop i = if 2 * i > last then () (* 子なし *)
            else if 2 * i = last then (* 子1人 *)
                if Dijk.compare h.(2 * i) h.(i) >= 0 then () else Array.swap h (2 * i) i
            else
                let j = if Dijk.compare h.(2 * i + 1) h.(2 * i) >= 0
                    then 2 * i
                    else 2 * i + 1
                in
                if Dijk.compare h.(j) h.(i) >= 0 then ()
                else (Array.swap h j i; loop j)
        in
        loop 1;
        (last, h)
        end
    let add (last, h) dist x =
        let last = last + 1 in
        let h = if last >= Array.length h
            then begin
                let h2 = Array.create ~len:(2 * Array.length h) zero in
                Array.blit h 0 h2 0 last;
                h2
            end else h
        in
        let rec loop i = if i = 1 then ()
            else if Dijk.compare h.(i) h.(i / 2) >= 0 then ()
            else (Array.swap h i (i / 2); loop (i / 2))
        in
        h.(last) <- to_tup dist x;
        loop last;
        (last, h)
    let singleton dist x = (1, Array.create ~len:100000 (to_tup dist x))
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if Int64.(dist > res.{v, money}) then loop mins else begin
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = (Dijk.t, Dijk.comparator_witness) Set.t
    let min_elt h = Option.map (Set.min_elt h) ~f:(fun (dist,v,money) -> (dist, (v,money)))
    let remove_min h = match Set.min_elt h with
        | None -> h
        | Some x -> Set.remove h x
    let add h dist (v,money) = Set.add h (dist, v, money)
    let singleton dist (v,money) = Set.singleton (module Dijk) (dist, v, money)
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if Int64.(dist > res.{v, money}) then loop mins else begin
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist <= res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = (Dijk.t, Dijk.comparator_witness) Set.t
    let min_elt h = Option.map (Set.min_elt h) ~f:(fun (dist,v,money) -> (dist, (v,money)))
    let remove_min h = match Set.min_elt h with
        | None -> h
        | Some x -> Set.remove h x
    let add h dist (v,money) = Set.add h (dist, v, money)
    let singleton dist (v,money) = Set.singleton (module Dijk) (dist, v, money)
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if Int64.(dist >= res.{v, money}) then loop mins else begin
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist < res.{v, money})
            then ((* res.{v, money} <- dist; *) H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist < res.{v, money})
            then ((* res.{v, money} <- dist; *) H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

module H = struct
    type t = (Dijk.t, Dijk.comparator_witness) Set.t
    let min_elt h = Option.map (Set.min_elt h) ~f:(fun (dist,v,money) -> (dist, (v,money)))
    let remove_min h = match Set.min_elt h with
        | None -> h
        | Some x -> Set.remove h x
    let add h dist (v,money) = Set.add h (dist, v, money)
    let singleton dist (v,money) = Set.singleton (module Dijk) (dist, v, money)
end

let dijk () = let rec loop mins =
    match H.min_elt mins with
    | None -> ()
    | Some (dist, (v, money)) ->
        let mins = H.remove_min mins in
        if Int64.(dist >= res.{v, money}) then loop mins else begin
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && Int64.(dist < res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && Int64.(dist < res.{v, money})
            then (res.{v, money} <- dist; H.add mins dist (v, money))
            else mins
        end in
        loop mins end
    in loop (H.singleton 0L (0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio
open Bigarray

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let used = Array2.create int8_signed c_layout n (money_inf+1)
let () = Array2.fill used 0
let res = Array2.create int64 c_layout n (money_inf+1)
let () = Array2.fill res dist_inf

(* cf. https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Map/index.html *)
module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

let dijk () = let rec loop mins =
    match Set.min_elt mins with
    | None -> ()
    | Some ((dist, v, money) as tup) ->
        let mins = Set.remove mins tup in
        if used.{v, money} <> 0 then loop mins else begin
        used.{v, money} <- 1 (* true *);
        res.{v, money} <- Int64.min res.{v, money} dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && used.{v, money} = 0
            then Set.add mins (dist, v, money)
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && used.{v, money} = 0
            then Set.add mins (dist, v, money)
            else mins
        end in
        loop mins end
    in loop (Set.singleton (module Dijk) (0L, 0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        let res_v = Array2.slice_left res v in
        let rec calc_min acc i =
            if i < Array1.dim res_v
            then calc_min Int64.(min acc res_v.{i}) (i+1)
            else acc
        in
        printf "%Ld\n" @@ calc_min dist_inf 0
    done


open Core
open Stdio

let scan_line fo g = Caml.Scanf.sscanf In_channel.(input_line_exn stdin) fo g
let scan_line_1 fo = scan_line fo (fun a -> a)
let scan_line_2 fo = scan_line fo (fun a b -> (a,b))
let scan_line_3 fo = scan_line fo (fun a b c -> (a,b,c))
let scan_line_4 fo = scan_line fo (fun a b c d -> (a,b,c,d))

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let n, m, s = scan_line_3 "%d %d %d"
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let u, v, un, ji = scan_line_4 "%d %d %d %Ld" in
        let u = u - 1 in let v = v - 1 in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s =
    Array.init n
    ~f:begin fun _ ->
        let x, y = scan_line_2 "%d %Ld" in
        let x = min x money_inf in
        (x,y)
    end

let used = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) false
let res = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) dist_inf

module Dijk = struct
    module T = struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end
    include T
    include Comparator.Make(T)
end

let dijk () = let rec loop mins =
    match Set.min_elt mins with
    | None -> ()
    | Some ((dist, v, money) as tup) ->
        let mins = Set.remove mins tup in
        if used.(v).(money) then loop mins else begin
        used.(v).(money) <- true;
        res.(v).(money) <- Int64.min res.(v).(money) dist;
        (* 銀貨に交換 *)
        let mins =
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            let money = money + fst maisu_jikan_s.(v) in
            if money <= money_inf && not used.(v).(money)
            then Set.add mins (dist, v, money)
            else mins
        in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:begin fun mins e ->
            let dist = Int64.(dist + e.jikan) in
            let v = e.cod in
            let money = money - e.unchin in
            if money >= 0 && not used.(v).(money)
            then Set.add mins (dist, v, money)
            else mins
        end in
        loop mins end
    in loop (Set.singleton (module Dijk) (0L, 0, s))

let () =
    dijk ();
    for v = 1 to n - 1 do
        printf "%Ld\n" @@ Option.value_exn Int64.(Array.min_elt res.(v) ~compare)
    done


open Core
open Stdio

let read_line () = In_channel.(input_line_exn stdin)

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let [n;m;s] = read_line () |> String.split ~on:' ' |> List.map ~f:Int.of_string
let s = min money_inf s

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let [u; v; un; ji] = read_line () |> String.split ~on:' ' in
        let u = Int.of_string u - 1 in
        let v = Int.of_string v - 1 in
        let un = Int.of_string un in
        let ji = Int64.of_string ji in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s = Array.init n ~f:(fun _ ->
    let x,y = read_line () |> String.lsplit2_exn ~on:' ' in
    let x = min money_inf (Int.of_string x) in
    let y = Int64.of_string y in
    (x,y))

let used = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) false
let res = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) dist_inf

let rec dijk mins = match Set.min_elt mins with
    | None -> ()
    | Some ((dist, v, money) as tup) ->
        let mins = Set.remove mins tup in
        if used.(v).(money) then dijk mins else begin
        used.(v).(money) <- true;
        res.(v).(money) <- Int64.min res.(v).(money) dist;
        (* printf "%Ld (%d, %d)\n" res.(v).(money) v money; *)
        (* 銀貨に交換 *)
        let mins = let money = money + fst maisu_jikan_s.(v) in
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            if money <= money_inf && not used.(v).(money) (* && Int64.(dist < res.(v).(money)) *)
            then Set.add mins (dist, v, money)
            else mins in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:(fun mins ch ->
            let money = money - ch.unchin in
            let dist = Int64.(dist + ch.jikan) in
            let v = ch.cod in
            if money >= 0 && not used.(v).(money) (* && Int64.(dist < res.(v).(money)) *)
            then Set.add mins (dist, v, money)
            else mins) in
        dijk mins
        end

module DijkData : (Comparator.S with type t = int64 * int * int) = struct
    type t = int64 * int * int
    include Comparator.Make (struct
        type t = int64 * int * int
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end)
end

let () = dijk (Set.singleton (module DijkData) (0L, 0, s));
(* let () = dijk (Map.singleton (module Int64) 0L (0, s)); *)
    for v = 1 to n - 1 do
        printf "%Ld\n" @@ Option.value_exn (Array.min_elt res.(v) ~compare:Int64.compare)
    done


open Core
open Stdio

let read_line () = In_channel.(input_line_exn stdin)
let rep i0 n f = for i = i0 to n - 1 do
        f ()
    done
let t2_map f (a, b) = (f a, f b)

let money_inf = 50 * 50
let dist_inf = Int64.(10L ** 15L)
type edge_t = { cod : int; unchin : int; jikan : Int64.t }

let [n;m;s] = read_line () |> String.split ~on:' '
let n = Int.of_string n
let m = Int.of_string m
let s = Int64.of_string s
let s = Int64.(to_int_exn @@ min (of_int money_inf) s)

let edges = Array.create ~len:n []

let () =
    for i = 1 to m do
        let [s_u; s_v; s_un; s_ji] = read_line () |> String.split ~on:' ' in
        let u = Int.of_string s_u - 1 in
        let v = Int.of_string s_v - 1 in
        let un = Int.of_string s_un in
        let ji = Int64.of_string s_ji in
        edges.(u) <- { cod = v; unchin = un; jikan = ji } :: edges.(u);
        edges.(v) <- { cod = u; unchin = un; jikan = ji } :: edges.(v)
    done

let maisu_jikan_s = Array.init n ~f:(fun _ ->
    read_line () |> String.lsplit2_exn ~on:' ' |> (fun (x,y) ->
    let x = Int.(min (of_string x) money_inf) in
    let y = Int64.of_string y in
    (x,y)))

let used = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) false
let res = Array.make_matrix ~dimx:n ~dimy:(money_inf+1) dist_inf

let rec dijk mins = match Set.min_elt mins with
    | None -> ()
    | Some ((dist, v, money) as tup) ->
        let mins = Set.remove mins tup in
        if used.(v).(money) then dijk mins else begin
        used.(v).(money) <- true;
        res.(v).(money) <- Int64.min res.(v).(money) dist;
        (* 銀貨に交換 *)
        let mins = let money = money + fst maisu_jikan_s.(v) in
            let dist = Int64.(dist + snd maisu_jikan_s.(v)) in
            if money <= money_inf && not used.(v).(money)
            then Set.add mins (dist, v, money)
            else mins in
        (* 別の都市に移動 *)
        let mins = List.fold edges.(v) ~init:mins ~f:(fun mins ch ->
            let money = money - ch.unchin in
            let dist = Int64.(dist + ch.jikan) in
            let v = ch.cod in
            if money >= 0 && not used.(v).(money)
            then Set.add mins (dist, v, money)
            else mins) in
        dijk mins
        end

module DijkData : (Comparator.S with type t = (int64 * int * int)) = struct
    type t = (int64 * int * int)
    include Comparator.Make (struct
        type t = (int64 * int * int)
        let compare = Tuple3.compare ~cmp1:Int64.compare ~cmp2:compare ~cmp3:compare
        let sexp_of_t = Tuple3.sexp_of_t Int64.sexp_of_t Int.sexp_of_t Int.sexp_of_t
    end)
end

let () = dijk (Set.singleton (module DijkData) (0L, 0, s));
    for v = 1 to n - 1 do
        printf "%Ld\n" @@ Option.value_exn (Array.min_elt res.(v) ~compare:Int64.compare)
    done


module WeightedDirectedGraph
  (* 辺の重み *)
  (Weight : sig
    type t
    val zero : t
    val compare : t -> t -> int
  end)
  (* 経路長を優先度としたヒープの実装 *)
  (Heap : sig
    type t
    type elt (* 頂点に相当 *)
    type key = Weight.t (* 経路長に相当 *)
    (* 空なヒープを作る *)
    val make : unit -> t
    (* ヒープが空ならNoneを，
       そうでなければ経路長が最小となるbindingを返す
       返したbindingはヒープから削除される *)
    val take_min_binding : t -> (key * elt) option
    (* ヒープにbindingを追加する
       既に同じ頂点についてのbindingが追加されていたら，
       経路長の短い方だけを残しても良いし，何も考えずに追加してもよい．
       前者の実装ならダイクストラ法の実装が時間計算量O((V + E) log V)，
       空間計算量O(V)に改善する *)
    val add : t -> key -> elt -> unit
  end)
  (* 頂点を添字，経路長を要素とした配列の実装 *)
  (Array : sig
    type t
    type key = Heap.elt
    type elt = Heap.key
    (* 全ての頂点についての要素が無限大の経路長で初期化された配列を作る
       このとき，オーバーフローの恐れはないのでmax_int等で初期化してもよい  *)
    val make : unit -> t
    val get : t -> key -> elt
    val set : t -> key -> elt -> unit
  end)
: sig
  type weight = Array.elt
  type vertex = Array.key

  (* ダイクストラ法で最短経路を求める関数 *)
  val shortest_path :
    (* 最短経路を求めたいグラフの，ある頂点から伸びる辺に対してのイテレータ *)
    (vertex -> (vertex -> (weight -> weight) (* 辺を通った際のコストを加算する関数 *) -> unit) -> unit) ->
    (* 始点 *)
    vertex ->
    (* 終点を受け取って，始点からの最短距離を返す関数
       始点から辿り着けない場合，無限大を返す
       この関数を覚えておけば，呼び出しごとの途中までの計算結果がシェアされる *)
    (vertex -> weight)
end
= struct
  type weight = Array.elt
  type vertex = Array.key

  let shortest_path es s =
    let q = Heap.make () in
    let d = Array.make () in
    (* 始点への経路長を0にする *)
    Array.set d s Weight.zero;
    (* 既に最短距離が確定した辺へのクエリを高速化するため，
       ヒープの最小要素をメモしておく *)
    let min_binding = ref (Some (Weight.zero, s)) in
    let rec dijkstra t =
      match !min_binding with
      (* もう既に全ての頂点までの距離が分かっている *)
      | None -> Array.get d t
      | Some (w, u) ->
          match Array.get d t with
          (* 既に終点までの距離が分かっているので返す *)
          | x when 0 <= Weight.compare w x -> x
          (* 終点までの距離が分かっていないので，ダイクストラ法を続行 *)
          | _ ->
              (* 未だ頂点uを訪れていない *)
              if 0 <= Weight.compare (Array.get d u) w then
                es u (fun v f ->
                  (* uからvに伸びる辺を通った際の経路長 *)
                  let c = f w in
                  if 0 < Weight.compare (Array.get d v) c then
                    (Heap.add q c v; Array.set d v c));
              min_binding := Heap.take_min_binding q;
              dijkstra t in
    dijkstra
end

module Int = struct
  type t = int
  let zero = 0
  let compare = compare
end

module IntMap = Map.Make (Int)

let () = Scanf.scanf "%d %d %d\n" @@ fun n m s ->
  let es = Array.make n [] in
  for i = 0 to m - 1 do
    Scanf.scanf "%d %d %d %d\n" @@ fun u v a b ->
      es.(u - 1) <- (v - 1, a, b) :: es.(u - 1);
      es.(v - 1) <- (u - 1, a, b) :: es.(v - 1);
  done;
  let vs = Array.init n @@ fun _ -> Scanf.scanf "%d %d\n" @@ fun c d -> (c, d) in
  let module G = WeightedDirectedGraph (Int)
    (struct
      type t = int array list IntMap.t ref
      type key = int
      type elt = int array
      let make () = ref IntMap.empty
      let take_min_binding q =
        match IntMap.min_binding !q with
        | exception Not_found -> None
        | (w, [v]) -> q := IntMap.remove w !q; Some (w, v)
        | (w, v :: vs) -> q := IntMap.add w vs !q; Some (w, v)
      let add q w v  =
        q := IntMap.update w (fun vs -> Some (v :: Option.value ~default:[] vs)) !q
    end)
    (struct
      type t = (int, Bigarray.int_elt, Bigarray.c_layout) Bigarray.Genarray.t
      type elt = int
      type key = int array
      let make () =
        let d = Bigarray.Genarray.create Bigarray.int Bigarray.c_layout [| n; 2501 |] in
        Bigarray.Genarray.fill d max_int; d
      let get = Bigarray.Genarray.get
      let set = Bigarray.Genarray.set
    end) in
  let d = Fun.flip G.shortest_path [| 0; min 2500 s |] @@ fun [| v; w |] f ->
        List.iter (fun (u, a, b) ->
          if a <= w then
            f [| u; w - a |] (( + ) b)) es.(v);
        let (c, d) = vs.(v) in
        f [| v; min 2500 (w + c) |] (( + ) d) in
  for v = 1 to n - 1 do
    Printf.printf "%d\n" @@
    Array.fold_left min max_int @@
    Array.init 2501 @@ fun w -> d [| v; w |]
  done