/*
一开始想到了简单的深搜 维护当前可用的mi数组
然后回溯用哪个 不断更新新产生的mi
这样的问题是 由于mi不断产生 搜索规模扩大
不好 不好 下面是奇丑的WA掉的代码 做个反面教材
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,ans=0x3f3f3f3f,f[1055],s[1055],top,vis[1055];
void Dfs(int p,int c)
{
if(p<=0||p>n*2)return;
if(f[p]==0)s[++top]=p,f[p]=1;
if(p==n){ans=min(ans,c);return;}
if(c>ans)return;
for(int i=1;i<=top;i++)
if(vis[i]==0)
{
vis[i]=1;
Dfs(p+s[i],c+1);
Dfs(p-s[i],c+1);
vis[i]=0;
}
}
int main()
{
scanf("%d",&n);
ans=n;
Dfs(1,0);
printf("%d\n",ans);
return 0;
}
/*
正解是迭代加深
对于每次的搜索 我们限制最多能做几次运算
这样搜索的规模就大大减小
同样的维护已经得到的mi数组
数组的大小对应做了几次运算
加上几个剪枝:
如果mi中最大的<<(limit-k)都到不了n 搜索失败
生成新的mi的时候 尽量组合数大的 这样也可以减小规模
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 20
using namespace std;
int n,a[N*2];
bool Dfs(int k,int limit)
{
if(a[k]==n)return 1;
if(k==limit)return 0;
int maxx=0;
for(int i=0;i<=k;i++)maxx=max(maxx,a[k]);
if(maxx<<(limit-k)<n)return 0;
for(int i=k;i>=0;i--)
{
a[k+1]=a[i]+a[k];
if(Dfs(k+1,limit))return 1;
a[k+1]=a[k]-a[i];
if(Dfs(k+1,limit))return 1;
}
return 0;
}
int find()
{
if(n==1)return 0;
a[0]=1;
for(int i=1;i<=N;i++)
if(Dfs(0,i))return i;
}
int main()
{
scanf("%d",&n);
printf("%d\n",find());
return 0;
}