signature QUEUE = sig type 'a t exception QueueEmpty val empty : 'a t val push : 'a -> 'a t -> 'a t val peek : 'a t -> 'a val drop : 'a t -> 'a t val isEmpty : 'a t -> bool end structure Queue : QUEUE = struct datatype 'a t = Queue of ('a list * 'a list) exception QueueEmpty val empty = Queue([], []) fun normalForm (Queue ([], back)) = (Queue (List.rev back, [])) | normalForm queue = queue; fun push x (Queue (front, back)) = normalForm (Queue (front, x::back)) fun peek (Queue (h::_, _)) = h | peek (Queue ([], _)) = raise QueueEmpty fun drop (Queue (h::t, back)) = normalForm (Queue (t, back)) | drop (Queue ([], _)) = raise QueueEmpty fun isEmpty (Queue ([], [])) = true | isEmpty _ = false end fun readInt () = valOf (TextIO.scanStream (Int.scan StringCvt.DEC) TextIO.stdIn) fun intString n = if 0 <= n then Int.toString n else "-" ^ Int.toString (abs n) fun intToNumOfBit n = foldl (fn (c, acc) => if c = #"1" then acc + 1 else acc) 0 (explode (Int.fmt StringCvt.BIN n)) fun findAns target used queue = let val (depth, location) = Queue.peek queue in if location = target then depth else ( let val numOfBit = intToNumOfBit location val p = location + numOfBit val m = location - numOfBit val queue0 = Queue.drop queue val queue1 = if p <= target andalso Array.sub (used, p) = false then Queue.push (depth + 1, p) queue0 before Array.update (used, p, true) else queue0 val queue2 = if 1 <= m andalso Array.sub (used, m) = false then Queue.push (depth + 1, m) queue1 before Array.update (used, m, true) else queue1 in findAns target used queue2 end ) end val () = let val n = readInt () val used = Array.array (n + 1, false) val queue = Queue.empty val ans = (findAns n used (Queue.push (1, 1) queue) handle QueueEmpty => ~1) in print ((intString ans) ^ "\n") end