#include "bits/stdc++.h" using namespace std; using int64 = long long; template using p_que = priority_queue; template using rp_que = priority_queue, greater>; constexpr int INF = (1 << 30) - 1; constexpr int64 INF64 = (1ll << 60) - 1; #define rep(i, N) for(int i=0;i<(int)(N);++i) #define fs first #define sc second #define e_b emplace_back #define m_p make_pair #define all(x) x.begin(),x.end() #define rall(x) x.rbegin(),x.rend() template ostream& operator<<(ostream& os, const pair& p) { return os << "P(" << p.first << ", " << p.second << ")"; } template ostream& operator<<(ostream& os, const vector& v) { os << "["; for (auto& e : v) os << e << ", "; return os << "]"; } template ostream& operator<<(ostream& os, const map& m) { os << "{" << endl; for (auto& e : m) os << "(" << e.first << ", " << e.second << ")" << endl; return os << "}"; } template ostream& operator<<(ostream& os, const set& s) { os << "{" << endl; for (auto& e : s) os << ", " << e << endl; return os << "}"; } template vector make_v(size_t a, T b) { return vector(a, b); } template auto make_v(size_t a, Ts... ts) { return vector(a, make_v(ts...)); } int64 gcd(int64 x, int64 y) { if (x == 0 || y == 0) return 0; int64 r; while ((r = y % x) != 0) { y = x; x = r; } return x; } int64 lcm(int64 x, int64 y) { if (x == 0 || y == 0) return 0; return x / gcd(x, y) * y; } int dx[] = { -1, 0, 1, 0 }; int dy[] = { 0, 1, 0, -1 }; void Main(); signed main() { cin.tie(nullptr); ios_base::sync_with_stdio(false); cout << fixed << setprecision(30); Main(); } /*----------------------------Insert from here!----------------------------*/ template struct Edge { int from, to; T cost; Edge() : from(0), to(0), cost(0) {} Edge(int to, T cost) : from(-1), to(to), cost(cost) {} Edge(int from, int to, T cost) : from(from), to(to), cost(cost) {} Edge& operator=(const int& x) { to = x; return *this; } }; template using Edges = vector>; template using wGraph = vector>; using uwGraph = vector>; template using Matrix = vector>; template vector dijkstra(wGraph& g, int s) { const auto INF = numeric_limits::max(); vector dist(g.size(), INF); using P = pair; priority_queue, greater

> que; dist[s] = 0; que.emplace(dist[s], s); while (!que.empty()) { T cost; int idx; tie(cost, idx) = que.top(); que.pop(); if (dist[idx] < cost) continue; for (auto& e : g[idx]) { T next_cost = cost + e.cost;; if (dist[e.to] <= next_cost) continue; dist[e.to] = next_cost; que.emplace(dist[e.to], e.to); } } return dist; } /*----------------------------Insert above here----------------------------*/ void Main() { int N; cin >> N; vector v(N); wGraph G(N); rep(i, N) { int t = i + 1; while (t > 0) { if (t % 2 == 1) v[i]++; t /= 2; } if (i + v[i] < N) G[i].emplace_back(i + v[i], 1); if (i - v[i] >= 0) G[i].emplace_back(i - v[i], 1); } auto d = dijkstra(G, 0); cout << (d[N-1] == INT_MAX ? -1 : d[N-1] + 1) << endl; }