#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll unsigned long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
const int maxn =1e5+5;
const int mod=9999991;
const int ub=1e6;
const double e=2.71828;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:最开始有一堆石子,
定义一种操作,可以把一堆石子变成为
连续数字(和相同)代表的堆。
首先要用dp思想去考虑,
假设扫描到i位置,令:k,k+1,...k+j-1(共j个数字),
和为i,那么我们可以得到:j*(2*k+j-1)=2*i,
不难发现j<2*k+j-1,那么我们只要扫描根号2i内的因子,
判断其是否存在k即可。
找到j和k后,我们需要动态维护sg函数前缀和,开一个数组维护下就行,异或性质允许。
对于得到的新的sg值直接丢到f数组里面,为了节省时间把特判条件定为是否等于i,
最后通过f数组更新dp值(就是sg值),在中途如果发现sg值有0,立马更新答案即可。
时间复杂度O(n^(3/2))
*/
int dp[maxn],sum[maxn],ans[maxn],f[maxn];
int n,INF;
int main(){
scanf("%d",&n);
mst(ans,0xf);INF=ans[0];
for(int i=1;i<=n;i++){
int tmp=2*i;
for(int j=2;j*j<=tmp;j++) if(tmp%j==0){
int k=tmp/j+1-j;
if(k%2) continue;
k>>=1;
if(k<1) continue;
int ret=sum[k-1]^sum[k+j-1];
f[ret]=i;
if(!ret) ans[i]=min(ans[i],j);///必胜的条件
}
for(int j=0;;j++){///sg值不一定只有0和1,最好还是保险起见(虽然手动模拟时候并不觉得)
if(f[j]!=i){
dp[i]=j;
break;
}
}
sum[i]=sum[i-1]^dp[i];
}
///for(int i=1;i<=n;i++) cout<<dp[i]<<" ";puts("");
printf("%d\n",(ans[n]==INF)?-1:ans[n]);
return 0;
}