#include #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define rep(i,n) FOR(i,0,n) #define repr(i,n) for(int i=(n)-1;0<=i;--i) #define each(e,v) for(auto&& e:(v)) #define all(v) begin(v),end(v) #define DUMP(x) cerr<<#x<<": "<<(x)<; using vdouble = vector; using vstring = vector; using ll = long long; template void chmin(T& a, const T& b) { a = min(a, b); } template void chmax(T& a, const T& b) { a = max(a, b); } constexpr int popcnt(int a) { return __builtin_popcount(a); } template using Graph = vector>; struct Edge { int to, cost; Edge(int to, int cost): to(to), cost(cost) {} }; template void addEdge(Graph& graph, int from, int to, int cost) { graph[from].push_back(E(to, cost)); } template struct Dijkstra { vector res; template Dijkstra(const Graph& graph, int s) { res = vector(graph.size(), INF); using P = pair; // cost, to priority_queue, greater

> Q; Q.push(P(0, s)); res[s] = 0; while(!Q.empty()) { const T cost = Q.top().first; const int to = Q.top().second; Q.pop(); if(res[to] < cost) continue; for(E e: graph[to]) { if(cost + e.cost < res[e.to]) { res[e.to] = cost + e.cost; Q.push(P(res[e.to], e.to)); } } } } }; int main() { int N; cin >> N; vint to(N); rep(i, N) to[i] = popcnt(i+1); Graph graph(N); rep(i, N) { if(i + to[i] < N) addEdge(graph, i, i + to[i], 1); if(0 < i - to[i]) addEdge(graph, i, i - to[i], 1); } const int inf = 1e9; Dijkstra dijk(graph, 0); if(dijk.res[N-1] == inf) cout << -1 << endl; else cout << (dijk.res[N-1]+1) << endl; return 0; }