using System;
using System.Collections;
namespace CodeIq
{
internal class Program
{
/// 各数値に対応するビットフラグ数のテーブル
private static Hashtable _bitCountTable;
/// すごろくマス数
private static int _n;
/// 計算要素スタック
private static Stack _stack;
/// 位置に対応する最短手順数
private static Hashtable _history;
/// 現時点での最短手
private static int _nowBestOrderCount;
///
/// Carol は特殊なすごろくをしようとしている。
///
/// 1からNの番号がふられている一直線に並べられているN個のマスがある。
/// 1から開始のマスとして、ゴールはNが書かれているマスとする。
///
/// その場に書かれている数字の2進数で表現した時の1のビット数 だけ「前」または「後」に進めることができる。
/// (1未満とN+1以上のマスには移動することは出来ない、正確にNにならないとゴールできない)
///
/// 自然数Nを与えられた時、ゴールに到達できる最短の移動数(開始のマスへも移動にカウントする)を求めてください。
/// 到達できない場合は-1を出力してください。
///
/// 開始のマスがすでにゴールになっている場合もあリます。
///
private static void Main()
{
var _n = int.Parse( Console.ReadLine() );
//_n = 11;
_nowBestOrderCount = int.MaxValue;
_stack = new Stack();
_stack.Push( 1 );
_history = new Hashtable();
_history.Add( 1, 1 );
var getBitCount = new Func( target =>
{
var bitCount = 0;
for( ; target > 0; target &= target - 1 )
bitCount++;
return bitCount;
} );
_bitCountTable = new Hashtable();
for( var i = 1; i < _n; i++ )
_bitCountTable[i] = getBitCount( i );
for( var i = 1; i <= _n; i++ )
_history[i] = int.MaxValue;
// ゴールまでの経路を計算する
var result = Calculate( 1 );
//Debug.Print( ( result != int.MaxValue ? result : -1 ).ToString() );
Console.WriteLine( ( result != int.MaxValue ? result : -1 ) );
}
private static int Calculate( int orderCount )
{
// 現時点での最短手を超過している場合はそれ以上計算しても無駄
var pos = (int)_stack.Pop();
if( orderCount > _nowBestOrderCount )
return int.MaxValue;
// 前方向と後方向への移動をそれぞれ計算する
// ※前→後ろの順でチェックする
if( pos == _n )
return orderCount;
// 移動先が範囲外だったり、前回来た時よりも手数を上回っている場合は処理しない
// この時点で手数が上回っている場合はどうやっても巻き返せない
var calcCount = 0;
var backward = pos - (int)_bitCountTable[pos];
if( ( backward > 0 && (int)_history[backward] > orderCount + 1 ) )
{
_stack.Push( backward );
_history[backward] = orderCount + 1;
calcCount ++;
}
var forward = pos + (int)_bitCountTable[pos];
if( forward <= _n && ( (int)_history[forward] > orderCount + 1 ) )
{
_stack.Push( forward );
_history[forward] = orderCount + 1;
calcCount++;
}
var result = int.MaxValue;
for( var i = 0; i < calcCount; i++ )
{
var calculatedCount = Calculate( orderCount + 1 );
if( result > calculatedCount )
result = calculatedCount;
if( _nowBestOrderCount > result )
_nowBestOrderCount = result;
}
return result;
}
}
}