let readInt () = Scanf.scanf " %d" (fun x -> x)

let (+~) (x0, y0) (x1, y1) = (x0 + x1, y0 + y1)
let (-~) (x0, y0) (x1, y1) = (x0 - x1, y0 - y1)
let dist (dx, dy) = abs dx + abs dy
let par (dx, dy) = (dx + dy) mod 2 |> abs

type sgn = Neg | Nonneg
type reflection = Same | Flip

let normSgn dx = if dx < 0 then (Neg, -dx) else (Nonneg, dx)
let denormSgn sx dx = if sx = Neg then -dx else dx

let norm (dx, dy) =
  let (sx, dx') = normSgn dx in
  let (sy, dy') = normSgn dy in
  let (refl, normed) = if dx' < dy' then (Flip, (dy', dx')) else (Same, (dx', dy')) in
  assert (snd normed >= 0);
  assert (snd normed <= fst normed);
  (normed, (sx, sy, refl))

let denorm (sx, sy, refl) (dx, dy) =
  let (dx, dy) = if refl = Flip then (dy, dx) else (dx, dy) in
  (denormSgn sx dx, denormSgn sy dy)

(*
let testNormDenorm =
  QCheck.Test.make ~count:1000 ~name:"denorm . norm = id"
    QCheck.(pair int int)
    (fun p -> (*Printf.eprintf "%d %d\n" (fst p) (snd p);*) let (p', tr) = norm p in denorm tr p' = p)
*)

(*
let finishIn2 k (dx, dy) =
  let ((dx', dy'), tr) = norm (dx, dy) in
  let dx0 = dx' - dy' in
  let dy0 = k - dx0 in
  Printf.eprintf "finishIn2: (%d, %d) (%d, %d) (%d, %d)\n" dx' dy' dx0 dy0 (dx'-dx0) (dy'-dy0);
  let m0 = denorm tr (dx0, dy0) in
  let m1 = denorm tr (dx' - dx0, dy' - dy0) in
  Printf.eprintf "(%d, %d) (%d, %d) end finishIn2\n" (fst m0) (snd m0) (fst m1) (snd m1);
  (m0, m1)

let testFinishIn2 =
  QCheck.Test.make ~count:1 ~name:"finishIn2 finishes w/ 2 valid moves"
    QCheck.(pair (1 -- 1_000_000_000) (pair int int))
    (fun (k, (dx0, dy0)) ->
      QCheck.assume (k > 0);
      let sq x = (x mod (2*k-1) + 2*k-1) mod (2*k-1) - (k-1) in
      let d = (sq dx0, sq dy0) in
      QCheck.assume (d <> (0, 0));
      QCheck.assume (dist d < k);
      QCheck.assume (((fst d + snd d) mod 2 = 0) = (k mod 2 = 0));
      Printf.eprintf "start: %d (%d, %d)\n" k (fst d) (snd d);
      let (m0, m1) = finishIn2 k d in
      Printf.eprintf "(%d, %d) (%d, %d)" (fst m0) (snd m0) (fst m1) (snd m1);
      Printf.eprintf "\n";
      assert (dist m0 = k);
      assert (dist m1 = k);
      m0 +~ m1 = d)
*)

let onDiamond k (dx, dy) =
  let ((dx', dy'), tr) = norm (dx, dy) in
  let diag = dx' - dy' in
  assert (diag mod 2 = 0);
  let diag = diag / 2 in
  denorm tr (diag, k - diag)

(*
let testOnDiamond =
  QCheck.Test.make ~count:1000 ~name:"onDiamond gets target on diamond"
    QCheck.(pair (1 -- 1_000_000) (pair int int))
    (fun (k, (dxt, dyt)) ->
      QCheck.assume (k > 0);
      let sq x = (x mod (4*k+1) + (4*k+1)) mod (4*k+1) - (2*k) in
      let d = (sq dxt, sq dyt) in
      QCheck.assume (d <> (0, 0));
      QCheck.assume (dist d <> k);
      QCheck.assume (dist d < 2*k);
      QCheck.assume (par d = 0);
      (*Printf.eprintf "%d (%d, %d) %d\n" k (fst d) (snd d) (dist d);*)
      let m = onDiamond k d in
      dist (d -~ m) = k)
*)

(*
let straightTo k (dx, dy) =
  let ((dx', dy'), tr) = norm (dx, dy) in
  let d = dx' + dy' in
  let dx1 = (k*dx' + d/2) / d in
  denorm tr (dx1, k - dx1)
*)

let toward k (dx, dy) =
  let ((dx', _), tr) = norm (dx, dy) in
  let dx' = min k dx' in
  (*Printf.eprintf "toward %d (%d %d) (normed: %d, %d)\n" k dx dy dx' (k-dx');*)
  denorm tr (dx', k - dx')

let solve k ((xt, yt) as targ) =
  if k mod 2 = 0 && par (xt, yt) <> 0 then None
  else
  let rec go ms cur =
    let delt = targ -~ cur in
    let d = dist delt in
    if d = 0 then ms
    else
    let move =
      if d >= 2*k || d = k || k mod 2 <> 0 && par delt <> 0 then toward
      else onDiamond
    in
    let m = move k delt in
    let cur' = cur +~ m in
    go (cur' :: ms) cur'
  in Some (go [] (0, 0) |> List.rev)
  (*
  if k mod 2 = 0 && (x0 + y0) mod 2 <> 0 then None
  else
  let rec go ms cur =
    let delt = targ -~ cur in
    let d = dist delt in
    if d = 0 then ms
    else if d < k then
      let (m0, m1) = finishIn2 k delt in
      let cur' = cur +~ m0 in
      let cur'' = cur' +~ m1 in
      assert (cur'' = targ);
      cur'' :: cur' :: ms
    else
      let cur' = cur +~ straightTo k delt in
      go (cur' :: ms) cur'
  in Some (go [] (0, 0) |> List.rev)
  *)

(*
let bound k targ =
  let d = dist targ in
  if d = k then 1
  else
  let x = (d + k - 1) / k in
  let baseline =
    if k mod 2 = 0 then (if par targ <> 0 then max_int else x)
    else x
  in
  let tooClose = if d < k then 1 else 0 in
  let baseline = baseline + tooClose in
  baseline + (if k mod 2 <> 0 && baseline mod 2 <> par targ then 1 else 0)

let check k targ ms =
  let n = List.length ms in
  let ms0 = (0, 0) :: ms in
  let ms1 = ms in
  try begin
    (try List.iter2 (fun p0 p1 -> if dist (p1 -~ p0) <> k then raise Exit) ms0 ms1
    with Invalid_argument _ -> ());
    let lst = List.nth ms (n-1) in
    Printf.eprintf "got here (%d, %d) (%d, %d)\n" (fst lst) (snd lst) (fst targ) (snd targ);
    List.nth ms (n-1) = targ
  end
  with Exit -> false

let testSolve =
  QCheck.Test.make ~count:50 ~name:"solve is sound and achieves bound"
    QCheck.(triple int (-100_000 -- 100_000) (-100_000 -- 100_000))
    (fun (k, x, y) ->
      Printf.eprintf "started\n";
      QCheck.assume (k > 0);
      QCheck.assume (max (abs x) (abs y) <= 100_000);
      Printf.eprintf "got further\n";
      match solve k (x, y) with
      | None -> true
      | Some ms ->
          let n = List.length ms in
          Printf.eprintf "%d (%d, %d) %d %d\n" k x y n (bound k (x, y));
          if n < 10 then begin
            Printf.eprintf "[";
            List.iter (fun (dx, dy) -> Printf.eprintf "(%d, %d), " dx dy) ms;
            Printf.eprintf "]\n"
          end;
          let getsThere = check k (x, y) ms in
          let fast = n <= bound k (x, y) in
          Printf.eprintf "%b %b\n" getsThere fast;
          getsThere && fast)
*)

let main () =
  let k = readInt () in
  let x = readInt () in
  let y = readInt () in
  match solve k (x, y) with
  | None -> print_endline "-1"
  | Some ms ->
      Printf.printf "%d\n" (List.length ms);
      ms |> List.iter begin fun (x, y) ->
        Printf.printf "%d %d\n" x y
      end

(*
let testMain () =
  print_endline "Testing...";
  QCheck.Test.check_exn testNormDenorm;
  (*QCheck.Test.check_exn testFinishIn2;*)
  QCheck.Test.check_exn testOnDiamond;
  print_endline "got to testSolve";
  QCheck.Test.check_exn testSolve;
  print_endline "...done testing"


let () = testMain ()
*)

let () = main ()


Measured memory_bytes: 20224