#define _CRT_SECURE_NO_DEPRECATE
#define _SECURE_SCL 0

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <iostream>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <cctype>
#include <sstream>
#include <cassert>
#include <bitset>
#include <memory.h>
#include <complex>
#include <iomanip>

using namespace std;

#pragma comment(linker, "/STACK:200000000")

typedef long long int64;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define fore(i, a, n) for(int i = (int)(a); i < (int)(n); i++)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) (int(a.size()) - 1)
#define all(a) a.begin(), a.end()

const double EPS = 1E-9;
const int INF = 1000000000;
const int64 INF64 = (int64) 1E18;
const double PI = 3.1415926535897932384626433832795;

const int MAGIC = 80;

const int SZ = (int)30;
const int BASE = (int)1E9;
const int LBASE = 9;
#define SLBASE "9"

struct bigint {
  int a[SZ];
  int len;
  bool neg;

  bool is_zero() const {
    return len == 1 && a[0] == 0;
  }

  int sign() const {
    if (is_zero())
      return 0;
    return neg ? -1 : +1;
  }

  bigint abs() const {
    if (neg)
      return -*this;
    return *this;
  }

  void norm() {
    while (len > 1 && a[len - 1] == 0)
      len--;
    if (is_zero())
      neg = false;
  }

  bigint() {
    len = 1;
    memset(a, 0, sizeof(a));
  }

  explicit bigint(const string& s) {
    len = 0;
    memset(a, 0, sizeof(a));

    neg = s[0] == '-';
    int lf = int(neg);
    if (s[0] == '+')
      lf = 1;

    for (int i = (int)s.size() - 1; i >= lf; i -= LBASE) {
      int cur = 0;
      for (int j = max(lf, i - LBASE + 1); j <= i; j++)
        cur = cur * 10 + s[j] - '0';
      a[len++] = cur;
    }

    norm();
  }

  bigint(int64 x) {
    len = 1;
    memset(a, 0, sizeof(a));
    neg = false;
    if (x < 0) {
      neg = true;
      x *= -1;
    }

    int i = 0;
    for (i = 0; x != 0; i++) {
      a[i] = int(x % BASE);
      x /= BASE;
    }
    len = max(len, i);

    norm();
  }

  string string_value() const {
    char buf[20];
    sprintf(buf, "%d", a[len - 1]);
    string res(buf);

    ford(i, len - 1) {
      sprintf(buf, "%0" SLBASE "d", a[i]);
      res += buf;
    }

    if (neg)
      res = "-" + res;

    return res;
  }

  string str() const {
    return string_value();
  }

  int64 int_value() const {
    int64 res = 0;
    ford(i, len)
      res = res * BASE + a[i];
    if (neg)
      res *= -1;
    return res;
  }

  bigint operator-() const {
    bigint res(*this);
    res.neg ^= true;
    res.norm();
    return res;
  }

  void operator += (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = p;
      return;
    }

    if (neg != p.neg) {
      *this -= -p;
      return;
    }

    int i;
    int carry = 0;
    for (i = 0; i < p.len || carry != 0; i++) {
      carry += a[i] + p.a[i];

      int ncarry = 0;
      while (carry >= BASE) {
        carry -= BASE;
        ncarry++;
      }
      a[i] = carry;
      carry = ncarry;
    }
    len = max(len, i);

    norm();
  }

  void operator -= (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = -p;
      return;
    }

    if (neg != p.neg) {
      *this += -p;
      return;
    }

    len = max(len, p.len);

    int i;
    int carry = 0;
    for (i = 0; (i < p.len || carry != 0) && i < len; i++) {
      carry += a[i] - p.a[i];

      int ncarry = 0;
      while (carry < 0) {
        carry += BASE;
        ncarry--;
      }
      a[i] = carry;
      carry = ncarry;
    }
    if (carry != 0)
      a[len++] = carry;

    if (a[len - 1] < 0) {
      forn(j, len - 1)
        a[j] = BASE - 1 - a[j];
      a[len - 1] = 0;

      for (i = 0; ; i++)
        if (++a[i] < BASE)
          break;
        else
          a[i] = 0;
      len = max(len, i + 1);

      neg ^= true;
    }

    norm();
  }

  void operator *= (int x) {
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int i;
    int64 carry = 0;
    for (i = 0; i < len || carry != 0; i++) {
      carry += a[i] * int64(x);
      a[i] = int(carry % BASE);
      carry /= BASE;
    }
    len = max(len, i);

    norm();
  }

  void operator /= (int x) {
    if (x == 0)
      throw;
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int64 carry = 0;
    ford(i, len) {
      carry = carry * BASE + a[i];
      a[i] = int(carry / x);
      carry %= x;
    }

    norm();
  }

  int operator % (int x) const {
    if (x <= 0)
      throw;

    int carry = 0;
    ford(i, len)
      carry = (carry * int64(BASE) + a[i]) % x;

    if (neg && carry != 0)
      carry = x - carry;

    return carry;
  }

  bigint operator * (const bigint& b) const {
    bigint res;
    res.neg = neg ^ b.neg;
    forn(i, len) {
      int j;
      int64 carry = 0;
      for (j = 0; j < b.len || carry != 0; j++) {
        carry += res.a[i + j] + a[i] * int64(b.a[j]);
        res.a[i + j] = int(carry % BASE);
        carry /= BASE;
      }
      res.len = max(res.len, i + j);
    }
    res.norm();
    return res;
  }

  int cmp(const bigint& p) const {
    int lf = -1, rg = +1;
    if (neg) {
      if (!p.neg)
        return -1;
      swap(lf, rg);
    }

    if (len != p.len)
      return len < p.len ? lf : rg;

    ford(i, len)
      if (a[i] != p.a[i])
        return a[i] < p.a[i] ? lf : rg;
    return 0;
  }

  pair<bigint, bigint> divide(bigint b) const {
    if (b.is_zero())
      throw;

    bigint a = *this;
    bigint res;
    bool res_neg = a.neg ^ b.neg;
    a.neg = b.neg = false;

    int diff = max(0, (a.len - b.len - 1) * LBASE);
    bigint pw10("1" + string(diff, '0'));
    b *= pw10;
    while (b <= a) {
      bigint nb = b * 10;
      if (nb > a)
        break;
      b = nb;
      pw10 *= 10;
    }

    while (!pw10.is_zero()) {
      while (b <= a) {
        a -= b;
        res += pw10;
      }

      b /= 10;
      pw10 /= 10;
    }

    res.neg = res_neg;
    res.norm();
    return mp(res, a);
  }

  bool overflow() const {
    return a[SZ - 1] != 0;
  }

  bigint operator + (const bigint& b) const {
    bigint res(*this);
    res += b;
    return res;
  }

  bigint operator - (const bigint& b) const {
    bigint res(*this);
    res -= b;
    return res;
  }

  bigint operator * (int x) const {
    bigint res(*this);
    res *= x;
    return res;
  }

  void operator *= (const bigint& b) {
    *this = *this * b;
  }

  bigint operator / (int x) const {
    bigint res(*this);
    res /= x;
    return res;
  }

  void operator %= (int x) {
    *this = bigint(*this % x);
  }

  void operator /= (const bigint& p) {
    *this = divide(p).fs;
  }

  bigint operator / (const bigint& p) const {
    return divide(p).fs;
  }

  void operator %= (const bigint& p) {
    *this = divide(p).sc;
  }

  bigint operator % (const bigint& p) const {
    return divide(p).sc;
  }

  bool operator < (const bigint& p) const {
    return cmp(p) < 0;
  }

  bool operator <= (const bigint& p) const {
    return cmp(p) <= 0;
  }

  bool operator > (const bigint& p) const {
    return cmp(p) > 0;
  }

  bool operator >= (const bigint& p) const {
    return cmp(p) >= 0;
  }

  bool operator == (const bigint& p) const {
    return cmp(p) == 0;
  }

  bool operator != (const bigint& p) const {
    return cmp(p) != 0;
  }
};

bigint sqrt64(bigint a) {
  bigint l = 0;
  bigint r("1000000000000000000000000000000000000000000000000000000000000000000000000000000");
  while (r - l > 1) {
    bigint mid = (l + r) / 2;

    if (mid * mid <= a)
      l = mid;
    else
      r = mid;
  }

  if (r * r == a)
    return r;
  if (l * l == a)
    return l;
  return -1;
}

int main() {
#ifdef RADs_project
  freopen("input.txt", "rt", stdin);
  freopen("output.txt", "wt", stdout);
#endif

  string str;
  cin >> str;
  bigint n(str);

  bigint b(-1);
  bigint pw2(1);
  vector<bigint> ans;
  for (int k = 0; k < MAGIC; k++) {
    if (k)
      b += pw2;
    pw2 *= 2;

    bigint d = b * b + bigint(8) * n;
    d = sqrt64(d);
    if (d == -1)
      continue;

    bigint x = -b + d;
    if (x % 2)
      continue;

    x /= 2;

    forn(i, k)
      x *= 2;

    ans.pb(x);
  }

  sort(all(ans));
  ans.erase(unique(all(ans)), ans.end());

  forn(i, ans.size())
    cout << ans[i].str() << endl;

  if (ans.empty())
    puts("-1");

  return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#define _SECURE_SCL 0

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <iostream>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <cctype>
#include <sstream>
#include <cassert>
#include <bitset>
#include <memory.h>
#include <complex>
#include <iomanip>

using namespace std;

#pragma comment(linker, "/STACK:200000000")

typedef long long int64;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define fore(i, a, n) for(int i = (int)(a); i < (int)(n); i++)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) (int(a.size()) - 1)
#define all(a) a.begin(), a.end()

const double EPS = 1E-9;
const int INF = 1000000000;
const int64 INF64 = (int64) 1E18;
const double PI = 3.1415926535897932384626433832795;

const int MAGIC = 100;

const int SZ = (int)100;
const int BASE = (int)1E9;
const int LBASE = 9;
#define SLBASE "9"

struct bigint {
  int a[SZ];
  int len;
  bool neg;

  bool is_zero() const {
    return len == 1 && a[0] == 0;
  }

  int sign() const {
    if (is_zero())
      return 0;
    return neg ? -1 : +1;
  }

  bigint abs() const {
    if (neg)
      return -*this;
    return *this;
  }

  void norm() {
    while (len > 1 && a[len - 1] == 0)
      len--;
    if (is_zero())
      neg = false;
  }

  bigint() {
    len = 1;
    memset(a, 0, sizeof(a));
  }

  explicit bigint(const string& s) {
    len = 0;
    memset(a, 0, sizeof(a));

    neg = s[0] == '-';
    int lf = int(neg);
    if (s[0] == '+')
      lf = 1;

    for (int i = (int)s.size() - 1; i >= lf; i -= LBASE) {
      int cur = 0;
      for (int j = max(lf, i - LBASE + 1); j <= i; j++)
        cur = cur * 10 + s[j] - '0';
      a[len++] = cur;
    }

    norm();
  }

  bigint(int64 x) {
    len = 1;
    memset(a, 0, sizeof(a));
    neg = false;
    if (x < 0) {
      neg = true;
      x *= -1;
    }

    int i = 0;
    for (i = 0; x != 0; i++) {
      a[i] = int(x % BASE);
      x /= BASE;
    }
    len = max(len, i);

    norm();
  }

  string string_value() const {
    char buf[20];
    sprintf(buf, "%d", a[len - 1]);
    string res(buf);

    ford(i, len - 1) {
      sprintf(buf, "%0" SLBASE "d", a[i]);
      res += buf;
    }

    if (neg)
      res = "-" + res;

    return res;
  }

  string str() const {
    return string_value();
  }

  int64 int_value() const {
    int64 res = 0;
    ford(i, len)
      res = res * BASE + a[i];
    if (neg)
      res *= -1;
    return res;
  }

  bigint operator-() const {
    bigint res(*this);
    res.neg ^= true;
    res.norm();
    return res;
  }

  void operator += (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = p;
      return;
    }

    if (neg != p.neg) {
      *this -= -p;
      return;
    }

    int i;
    int carry = 0;
    for (i = 0; i < p.len || carry != 0; i++) {
      carry += a[i] + p.a[i];

      int ncarry = 0;
      while (carry >= BASE) {
        carry -= BASE;
        ncarry++;
      }
      a[i] = carry;
      carry = ncarry;
    }
    len = max(len, i);

    norm();
  }

  void operator -= (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = -p;
      return;
    }

    if (neg != p.neg) {
      *this += -p;
      return;
    }

    len = max(len, p.len);

    int i;
    int carry = 0;
    for (i = 0; (i < p.len || carry != 0) && i < len; i++) {
      carry += a[i] - p.a[i];

      int ncarry = 0;
      while (carry < 0) {
        carry += BASE;
        ncarry--;
      }
      a[i] = carry;
      carry = ncarry;
    }
    if (carry != 0)
      a[len++] = carry;

    if (a[len - 1] < 0) {
      forn(j, len - 1)
        a[j] = BASE - 1 - a[j];
      a[len - 1] = 0;

      for (i = 0; ; i++)
        if (++a[i] < BASE)
          break;
        else
          a[i] = 0;
      len = max(len, i + 1);

      neg ^= true;
    }

    norm();
  }

  void operator *= (int x) {
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int i;
    int64 carry = 0;
    for (i = 0; i < len || carry != 0; i++) {
      carry += a[i] * int64(x);
      a[i] = int(carry % BASE);
      carry /= BASE;
    }
    len = max(len, i);

    norm();
  }

  void operator /= (int x) {
    if (x == 0)
      throw;
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int64 carry = 0;
    ford(i, len) {
      carry = carry * BASE + a[i];
      a[i] = int(carry / x);
      carry %= x;
    }

    norm();
  }

  int operator % (int x) const {
    if (x <= 0)
      throw;

    int carry = 0;
    ford(i, len)
      carry = (carry * int64(BASE) + a[i]) % x;

    if (neg && carry != 0)
      carry = x - carry;

    return carry;
  }

  bigint operator * (const bigint& b) const {
    bigint res;
    res.neg = neg ^ b.neg;
    forn(i, len) {
      int j;
      int64 carry = 0;
      for (j = 0; j < b.len || carry != 0; j++) {
        carry += res.a[i + j] + a[i] * int64(b.a[j]);
        res.a[i + j] = int(carry % BASE);
        carry /= BASE;
      }
      res.len = max(res.len, i + j);
    }
    res.norm();
    return res;
  }

  int cmp(const bigint& p) const {
    int lf = -1, rg = +1;
    if (neg) {
      if (!p.neg)
        return -1;
      swap(lf, rg);
    }

    if (len != p.len)
      return len < p.len ? lf : rg;

    ford(i, len)
      if (a[i] != p.a[i])
        return a[i] < p.a[i] ? lf : rg;
    return 0;
  }

  pair<bigint, bigint> divide(bigint b) const {
    if (b.is_zero())
      throw;

    bigint a = *this;
    bigint res;
    bool res_neg = a.neg ^ b.neg;
    a.neg = b.neg = false;

    int diff = max(0, (a.len - b.len - 1) * LBASE);
    bigint pw10("1" + string(diff, '0'));
    b *= pw10;
    while (b <= a) {
      bigint nb = b * 10;
      if (nb > a)
        break;
      b = nb;
      pw10 *= 10;
    }

    while (!pw10.is_zero()) {
      while (b <= a) {
        a -= b;
        res += pw10;
      }

      b /= 10;
      pw10 /= 10;
    }

    res.neg = res_neg;
    res.norm();
    return mp(res, a);
  }

  bool overflow() const {
    return a[SZ - 1] != 0;
  }

  bigint operator + (const bigint& b) const {
    bigint res(*this);
    res += b;
    return res;
  }

  bigint operator - (const bigint& b) const {
    bigint res(*this);
    res -= b;
    return res;
  }

  bigint operator * (int x) const {
    bigint res(*this);
    res *= x;
    return res;
  }

  void operator *= (const bigint& b) {
    *this = *this * b;
  }

  bigint operator / (int x) const {
    bigint res(*this);
    res /= x;
    return res;
  }

  void operator %= (int x) {
    *this = bigint(*this % x);
  }

  void operator /= (const bigint& p) {
    *this = divide(p).fs;
  }

  bigint operator / (const bigint& p) const {
    return divide(p).fs;
  }

  void operator %= (const bigint& p) {
    *this = divide(p).sc;
  }

  bigint operator % (const bigint& p) const {
    return divide(p).sc;
  }

  bool operator < (const bigint& p) const {
    return cmp(p) < 0;
  }

  bool operator <= (const bigint& p) const {
    return cmp(p) <= 0;
  }

  bool operator > (const bigint& p) const {
    return cmp(p) > 0;
  }

  bool operator >= (const bigint& p) const {
    return cmp(p) >= 0;
  }

  bool operator == (const bigint& p) const {
    return cmp(p) == 0;
  }

  bool operator != (const bigint& p) const {
    return cmp(p) != 0;
  }
};

bigint sqrt64(bigint a) {
  bigint l(0);
  bigint r("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
  while (r - l > 1) {
    bigint mid = (l + r) / 2;

    if (mid * mid <= a)
      l = mid;
    else
      r = mid;
  }

  if (r * r == a)
    return r;
  if (l * l == a)
    return l;
  return -1;
}

void check(int64 x, int64 n) {
  while (x % 2 == 0) {
    n -= x / 2;
    x /= 2;
  }

  if (n != x * (x - 1) / 2)
    throw;

}

vector<string> solve(string str) {
  bigint n(str);

  bigint b(-1);
  bigint pw2(1);
  vector<bigint> ans;
  for (int k = 0; k < MAGIC; k++) {
    if (k)
      b += pw2;
    pw2 *= 2;

    bigint d = b * b + bigint(8) * n;
    d = sqrt64(d);
    if (d == -1)
      continue;

    bigint x = -b + d;
    if (x % 2)
      continue;

    x /= 2;

    if (x % 2 == 0)
      continue;

    forn(i, k)
      x *= 2;

    ans.pb(x);
  }

  sort(all(ans));
  ans.erase(unique(all(ans)), ans.end());

  vector<string> res;
  forn(i, ans.size()) {
    cout << ans[i].str() << endl;
    //check(ans[i].int_value(), n.int_value());
  }

  if (ans.empty())
    puts("-1");

  return res;
}

int main() {
#ifdef RADs_project
  freopen("input.txt", "rt", stdin);
  freopen("output.txt", "wt", stdout);
#endif

  string str;
  cin >> str;

  solve(str);

  return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#define _SECURE_SCL 0

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <iostream>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <cctype>
#include <sstream>
#include <cassert>
#include <bitset>
#include <memory.h>
#include <complex>
#include <iomanip>

using namespace std;

#pragma comment(linker, "/STACK:200000000")

typedef long long int64;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; i--)
#define fore(i, a, n) for(int i = (int)(a); i < (int)(n); i++)
#define pb push_back
#define mp make_pair
#define fs first
#define sc second
#define last(a) (int(a.size()) - 1)
#define all(a) a.begin(), a.end()

const double EPS = 1E-9;
const int INF = 1000000000;
const int64 INF64 = (int64) 1E18;
const double PI = 3.1415926535897932384626433832795;

const int MAGIC = 100;

const int SZ = (int)100;
const int BASE = (int)1E9;
const int LBASE = 9;
#define SLBASE "9"

struct bigint {
  int a[SZ];
  int len;
  bool neg;

  bool is_zero() const {
    return len == 1 && a[0] == 0;
  }

  int sign() const {
    if (is_zero())
      return 0;
    return neg ? -1 : +1;
  }

  bigint abs() const {
    if (neg)
      return -*this;
    return *this;
  }

  void norm() {
    while (len > 1 && a[len - 1] == 0)
      len--;
    if (is_zero())
      neg = false;
  }

  bigint() {
    len = 1;
    memset(a, 0, sizeof(a));
  }

  explicit bigint(const string& s) {
    len = 0;
    memset(a, 0, sizeof(a));

    neg = s[0] == '-';
    int lf = int(neg);
    if (s[0] == '+')
      lf = 1;

    for (int i = (int)s.size() - 1; i >= lf; i -= LBASE) {
      int cur = 0;
      for (int j = max(lf, i - LBASE + 1); j <= i; j++)
        cur = cur * 10 + s[j] - '0';
      a[len++] = cur;
    }

    norm();
  }

  bigint(int64 x) {
    len = 1;
    memset(a, 0, sizeof(a));
    neg = false;
    if (x < 0) {
      neg = true;
      x *= -1;
    }

    int i = 0;
    for (i = 0; x != 0; i++) {
      a[i] = int(x % BASE);
      x /= BASE;
    }
    len = max(len, i);

    norm();
  }

  string string_value() const {
    char buf[20];
    sprintf(buf, "%d", a[len - 1]);
    string res(buf);

    ford(i, len - 1) {
      sprintf(buf, "%0" SLBASE "d", a[i]);
      res += buf;
    }

    if (neg)
      res = "-" + res;

    return res;
  }

  string str() const {
    return string_value();
  }

  int64 int_value() const {
    int64 res = 0;
    ford(i, len)
      res = res * BASE + a[i];
    if (neg)
      res *= -1;
    return res;
  }

  bigint operator-() const {
    bigint res(*this);
    res.neg ^= true;
    res.norm();
    return res;
  }

  void operator += (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = p;
      return;
    }

    if (neg != p.neg) {
      *this -= -p;
      return;
    }

    int i;
    int carry = 0;
    for (i = 0; i < p.len || carry != 0; i++) {
      carry += a[i] + p.a[i];

      int ncarry = 0;
      while (carry >= BASE) {
        carry -= BASE;
        ncarry++;
      }
      a[i] = carry;
      carry = ncarry;
    }
    len = max(len, i);

    norm();
  }

  void operator -= (const bigint& p) {
    if (p.is_zero())
      return;
    if (this->is_zero()) {
      *this = -p;
      return;
    }

    if (neg != p.neg) {
      *this += -p;
      return;
    }

    len = max(len, p.len);

    int i;
    int carry = 0;
    for (i = 0; (i < p.len || carry != 0) && i < len; i++) {
      carry += a[i] - p.a[i];

      int ncarry = 0;
      while (carry < 0) {
        carry += BASE;
        ncarry--;
      }
      a[i] = carry;
      carry = ncarry;
    }
    if (carry != 0)
      a[len++] = carry;

    if (a[len - 1] < 0) {
      forn(j, len - 1)
        a[j] = BASE - 1 - a[j];
      a[len - 1] = 0;

      for (i = 0; ; i++)
        if (++a[i] < BASE)
          break;
        else
          a[i] = 0;
      len = max(len, i + 1);

      neg ^= true;
    }

    norm();
  }

  void operator *= (int x) {
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int i;
    int64 carry = 0;
    for (i = 0; i < len || carry != 0; i++) {
      carry += a[i] * int64(x);
      a[i] = int(carry % BASE);
      carry /= BASE;
    }
    len = max(len, i);

    norm();
  }

  void operator /= (int x) {
    if (x == 0)
      throw;
    if (x < 0) {
      neg ^= true;
      x *= -1;
    }

    int64 carry = 0;
    ford(i, len) {
      carry = carry * BASE + a[i];
      a[i] = int(carry / x);
      carry %= x;
    }

    norm();
  }

  int operator % (int x) const {
    if (x <= 0)
      throw;

    int carry = 0;
    ford(i, len)
      carry = (carry * int64(BASE) + a[i]) % x;

    if (neg && carry != 0)
      carry = x - carry;

    return carry;
  }

  bigint operator * (const bigint& b) const {
    bigint res;
    res.neg = neg ^ b.neg;
    forn(i, len) {
      int j;
      int64 carry = 0;
      for (j = 0; j < b.len || carry != 0; j++) {
        carry += res.a[i + j] + a[i] * int64(b.a[j]);
        res.a[i + j] = int(carry % BASE);
        carry /= BASE;
      }
      res.len = max(res.len, i + j);
    }
    res.norm();
    return res;
  }

  int cmp(const bigint& p) const {
    int lf = -1, rg = +1;
    if (neg) {
      if (!p.neg)
        return -1;
      swap(lf, rg);
    }

    if (len != p.len)
      return len < p.len ? lf : rg;

    ford(i, len)
      if (a[i] != p.a[i])
        return a[i] < p.a[i] ? lf : rg;
    return 0;
  }

  pair<bigint, bigint> divide(bigint b) const {
    if (b.is_zero())
      throw;

    bigint a = *this;
    bigint res;
    bool res_neg = a.neg ^ b.neg;
    a.neg = b.neg = false;

    int diff = max(0, (a.len - b.len - 1) * LBASE);
    bigint pw10("1" + string(diff, '0'));
    b *= pw10;
    while (b <= a) {
      bigint nb = b * 10;
      if (nb > a)
        break;
      b = nb;
      pw10 *= 10;
    }

    while (!pw10.is_zero()) {
      while (b <= a) {
        a -= b;
        res += pw10;
      }

      b /= 10;
      pw10 /= 10;
    }

    res.neg = res_neg;
    res.norm();
    return mp(res, a);
  }

  bool overflow() const {
    return a[SZ - 1] != 0;
  }

  bigint operator + (const bigint& b) const {
    bigint res(*this);
    res += b;
    return res;
  }

  bigint operator - (const bigint& b) const {
    bigint res(*this);
    res -= b;
    return res;
  }

  bigint operator * (int x) const {
    bigint res(*this);
    res *= x;
    return res;
  }

  void operator *= (const bigint& b) {
    *this = *this * b;
  }

  bigint operator / (int x) const {
    bigint res(*this);
    res /= x;
    return res;
  }

  void operator %= (int x) {
    *this = bigint(*this % x);
  }

  void operator /= (const bigint& p) {
    *this = divide(p).fs;
  }

  bigint operator / (const bigint& p) const {
    return divide(p).fs;
  }

  void operator %= (const bigint& p) {
    *this = divide(p).sc;
  }

  bigint operator % (const bigint& p) const {
    return divide(p).sc;
  }

  bool operator < (const bigint& p) const {
    return cmp(p) < 0;
  }

  bool operator <= (const bigint& p) const {
    return cmp(p) <= 0;
  }

  bool operator > (const bigint& p) const {
    return cmp(p) > 0;
  }

  bool operator >= (const bigint& p) const {
    return cmp(p) >= 0;
  }

  bool operator == (const bigint& p) const {
    return cmp(p) == 0;
  }

  bool operator != (const bigint& p) const {
    return cmp(p) != 0;
  }
};

bigint sqrt64(bigint a) {
  bigint l(0);
  bigint r("100000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
  while (r - l > 1) {
    bigint mid = (l + r) / 2;

    if (mid * mid <= a)
      l = mid;
    else
      r = mid;
  }

  if (r * r == a)
    return r;
  if (l * l == a)
    return l;
  return -1;
}

int main() {
#ifdef RADs_project
  freopen("input.txt", "rt", stdin);
  freopen("output.txt", "wt", stdout);
#endif

  string str;
  cin >> str;
  bigint n(str);

  bigint b(-1);
  bigint pw2(1);
  vector<bigint> ans;
  for (int k = 0; k < MAGIC; k++) {
    if (k)
      b += pw2;
    pw2 *= 2;

    bigint d = b * b + bigint(8) * n;
    d = sqrt64(d);
    if (d == -1)
      continue;

    bigint x = -b + d;
    if (x % 2)
      continue;

    x /= 2;

    forn(i, k)
      x *= 2;

    ans.pb(x);
  }

  sort(all(ans));
  ans.erase(unique(all(ans)), ans.end());

  forn(i, ans.size())
    cout << ans[i].str() << endl;

  if (ans.empty())
    puts("-1");

  return 0;
}


#include<iostream>
#include<string>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
const int inf = ~0u>>2;
const int N = 5010;
int dp[2][N];
const int mod = 1000000007;
long long two[66];
int main() {
    long long n;
    scanf("%I64d",&n);
    two[0] = 1;
    for(int i = 1; i <= 62; i++) two[i] = two[i-1] * 2;
    vector<long long> ret;
    double s = sqrt(2.0*n);
    long long down = (long long)s - 10;
    if(down < 0) down = 0;
    long long up = (long long)s + 10;
    for(long long i = down; i <= up; i++) {
    	if(i*(i-1) == n * 2) ret.push_back(i);
    }
    for(int p = 1; p <= 61; p++) {
    	long long con = two[p] - 1;
    	con = con * 2 - 1;
        //if(p == 4) cout<<con<<endl;
    	long long l = 1 ,r = min((n*2/con) + 1 , 1000000000LL);
    	//if( p == 4) cout<<l<<" "<<r<<endl;
    	while(l <= r) {
    		long long mid = (l + r) >> 1;
    		if(mid*mid + con * mid == n * 2 ) {
    			if(mid&1) ret.push_back(two[p]*mid);
    			//cout<<p<<" "<<mid<<endl;
    			break;
    		}
    		if(mid*mid + con * mid > n * 2) {
    			r = mid - 1;
    		} else l = mid + 1;
    	}
    }
    if(ret.size() == 0){
    	puts("-1");
    }else {
    	sort(ret.begin(),ret.end());
    	int tot = unique(ret.begin(),ret.end()) - ret.begin();
    	for(int i = 0; i < tot; i++) printf("%I64d\n",ret[i]);
    }
	return 0;
}


#include<iostream>
#include<string>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
const int inf = ~0u>>2;
const int N = 5010;
int dp[2][N];
const int mod = 1000000007;
long long two[66];
int main() {
    long long n;
    scanf("%I64d",&n);
    two[0] = 1;
    for(int i = 1; i <= 62; i++) two[i] = two[i-1] * 2;
    vector<long long> ret;
    double s = sqrt(2.0*n);
    long long down = (long long)s - 10;
    if(down < 0) down = 0;
    long long up = (long long)s + 10;
    for(long long i = down; i <= up; i++) {
        if(i*(i-1) == n * 2 && (i&1)) ret.push_back(i);
    }
    for(int p = 1; p <= 61; p++) {
        long long con = two[p] - 1;
        con = con * 2 - 1;
     //   if(p == 1) cout<<con<<endl;
        long long l = 1 ,r = min((n*2/con) + 1 , 1000000000LL);
        //if( p == 1) cout<<l<<" "<<r<<endl;
        while(l <= r) {
            long long mid = (l + r) >> 1;
            if(mid*mid + con * mid == n * 2 ) {
                if(mid&1){
                //  cout<<p<<" "<<mid<<endl;
                    ret.push_back(two[p]*mid);
                }
                break;
            }
            if(mid*mid + con * mid > n * 2) {
                r = mid - 1;
            } else l = mid + 1;
        }
    }
    if(ret.size() == 0){
        puts("-1");
    }else {
        sort(ret.begin(),ret.end());
        int tot = unique(ret.begin(),ret.end()) - ret.begin();
        for(int i = 0; i < tot; i++) printf("%I64d\n",ret[i]);
    }
    return 0;
}


#include<iostream>
#include<string>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
const int inf = ~0u>>2;
const int N = 5010;
int dp[2][N];
const int mod = 1000000007;
 long long two[66];
int main() {
    long long n;
    scanf("%I64d",&n);
    two[0] = 1;
    for(int i = 1; i <= 61; i++) two[i] = two[i-1] * 2;
    vector<long long> ret;
    double s = sqrt(2.0*n);
    long long down = (long long)s - 10;
    if(down < 0) down = 0;
    long long up = (long long)s + 10;
    for(long long i = down; i <= up; i++) {
        if(i*(i-1) == n * 2) ret.push_back(i);
    }
    for(int p = 1; p <= 61; p++) {
        long long con = two[p] - 1;
        con = con * 2 - 1;
        //if(p == 2) cout<<con<<endl;
        long long l = 1 ,r = min((n*2/con) + 1 , 1000000000LL);
        //if(p == 2) cout<<l<<" "<<r<<endl;
        while(l <= r) {
            long long mid = (l + r) >> 1;
            if(mid*mid + con * mid == n * 2) {
                ret.push_back(two[p]*mid);
                break;
            }
            if(mid*mid + con * mid > n * 2) {
                r = mid - 1;
            } else l = mid + 1;
        }
    }
    if(ret.size() == 0){
        puts("-1");
    }else {
        sort(ret.begin(),ret.end());
        int tot = unique(ret.begin(),ret.end()) - ret.begin();
        for(int i = 0; i < tot; i++) printf("%I64d\n",ret[i]);
    }
    return 0;
}


#include<iostream>
#include<string>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
const int inf = ~0u>>2;
const int N = 5010;
int dp[2][N];
const int mod = 1000000007;
long long two[66];
int main() {
    long long n;
    scanf("%I64d",&n);
    two[0] = 1;
    for(int i = 1; i <= 62; i++) two[i] = two[i-1] * 2;
    vector<long long> ret;
    double s = sqrt(2.0*n);
    long long down = (long long)s - 10;
    if(down < 0) down = 0;
    long long up = (long long)s + 10;
    for(long long i = down; i <= up; i++) {
        if(i*(i-1) == n * 2 && (i&1)) ret.push_back(i);
    }
//    cout<<n*2<<endl;
    //  2828427122
    for(int p = 1; p <= 61; p++) {
        long long con = two[p] - 1;
        con = con * 2 - 1;
      //  if(p == 1) cout<<con<<endl;
        long long l = 1 ,r = min((n*2/con) + 1 , 2000000000LL);
      //  if(p == 1) cout<<l<<" "<<r<<endl;
        while(l <= r) {
            long long mid = (l + r) >> 1;
            if(mid*mid + con * mid == n * 2 ) {
                if(mid&1){
                //  cout<<p<<" "<<mid<<endl;
                    ret.push_back(two[p]*mid);
                }
                break;
            }
            if(mid*mid + con * mid > n * 2) {
                r = mid - 1;
            } else l = mid + 1;
        }
    }
    if(ret.size() == 0){
        puts("-1");
    }else {
        sort(ret.begin(),ret.end());
        int tot = unique(ret.begin(),ret.end()) - ret.begin();
        for(int i = 0; i < tot; i++) printf("%I64d\n",ret[i]);
    }
    return 0;
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else
#define LOCAL_TEST 1
#endif

#if LOCAL_TEST
#define LOCAL_ASSERT(expr) { if (!(expr)) {std::cout << "ASSERT FAILED: '" << #expr << "'" << std::endl; _CrtDbgBreak(); } }
#else
#define LOCAL_ASSERT(expr)
#endif

typedef long double double_t;
typedef std::string string8_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<string8_t> vector_string8_t;
typedef std::set<uint64_t> set_uint64_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}
template<typename T> inline void UpdateMin(T& a, const T b) {a = Min(a, b);}
template<typename T> inline void UpdateMax(T& a, const T b) {a = Max(a, b);}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

template<typename T> inline string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> inline bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const uint64_t Inf = 0xFFFFFFFFFFFFFFFFULL;
uint64_t Mul(uint64_t a, uint64_t b)
{
    if (Inf / a < b)
        return Inf;
    return a * b;
}

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        {
            const uint64_t MaxSlow = 10;
            for (uint64_t p = 1; p < MaxSlow; p += 2)
            {
                if (p > 2 * n)
                {
                    break;
                }
                const uint64_t m = 2 * pow2 + p;
                if (m > 2 * n + 3)
                {
                    break;
                }
                if (m < 3)
                {
                    p += 2;
                    continue;
                }

                const uint64_t x = p * (m - 3);

                if (x > 2 * n)
                    break;

                if (x == 2 * n)
                    ans.insert(pow2 * p);
            }
        }

        {
            uint64_t d = 1ULL << 63;
            uint64_t pz = 0;
            while (true)
            {
                if (pz > 2*n)
                {
                    break;
                }

                const uint64_t m = 2 * pow2 + pz;
                if (m > 2 * n + 3)
                {
                    break;
                }

                if (m >= 3)
                {
                    const uint64_t x = pz * (m - 3);

                    if (x > 2 * n)
                        break;

                    if (x == 2 * n && (pz % 2 == 1))
                        ans.insert(pow2 * pz);
                }

                {
                    bool shouldAdd = true;
                    if (pz + d > 2 * n)
                    {
                        shouldAdd = false;
                    }

                    if (2 * pow2 + pz + d > 2 * n + 3)
                    {
                        shouldAdd = false;
                    }

                    if (Mul(2 * pow2 + pz + d - 3, pz + d) > 2 * n)
                    {
                        shouldAdd = false;
                    }

                    if (shouldAdd)
                        pz += d;
                }
                if (d == 0)
                    break;
                d /= 2;
            }
        }
    }

    return ans;
}

set_uint64_t GetAnsSlow(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        {
            for (uint64_t p = 1; ; p += 2)
            {
                if (p > 2 * n)
                {
                    break;
                }
                const uint64_t m = 2 * pow2 + p;
                if (m > 2 * n + 3)
                {
                    break;
                }
                if (m < 3)
                {
                    p += 2;
                    continue;
                }

                const uint64_t x = p * (m - 3);

                if (x > 2 * n)
                    break;

                if (x == 2 * n)
                    ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

void Test()
{
    for (uint64_t n = 2; n <= 100000; n++)
    {
        const set_uint64_t& aRef = GetAnsSlow(n);
        const set_uint64_t& a = GetAns(n);
        LOCAL_ASSERT(a == aRef);
    }
}

int main()
{
#if LOCAL_TEST
//    Test();
#endif
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::set<uint64_t> set_uint64_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const double_t RangeHalf = 100000.0;

const uint64_t Inf = 0xFFFFFFFFFFFFFFFFULL;

uint64_t Add(uint64_t a, uint64_t b)
{
    if (Inf - a < b)
        return Inf;
    return a + b;
}

uint64_t Mul(uint64_t a, uint64_t b)
{
    if (Inf / a < b)
        return Inf;
    return a * b;
}

bool IsOk(uint64_t n, uint64_t pow2, uint64_t p)
{
    if (pow2 * 2 < 3)
    {
        uint64_t pp = Mul(p, p);
        pp -= p;
        return pp == 2 * n;
    }
    return Add(Mul(p, p), Mul(p, (pow2 * 2 - 3))) == 2 * n;
}

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        const double_t pow2f = (double_t)pow2;
        const double_t d = (pow2f * 2.0 - 3.0) + 8.0 * (double_t)n;
        if (IsLess(d, 0.0L))
            continue;

        for (uint64_t p = 1; p < 10; p += 2)
        {
            if (IsOk(n, pow2, p))
                ans.insert(pow2 * p);
        }

        const double_t x1f = (3.0 - pow2f + sqrt(d)) * 0.5;
        if (IsLess(x1f, 0.0L))
            continue;

        const double_t lbf = Max(x1f - RangeHalf, 0.0L);
        const double_t rbf = x1f + RangeHalf;

        const uint64_t lb = (uint64_t)lbf;
        const uint64_t rb = (uint64_t)rbf;

        for (uint64_t p = 2 * (lb / 2) + 1; p <= rb; p += 2)
        {
            if (IsOk(n, pow2, p))
            {
                ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, false)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::set<uint64_t> set_uint64_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const double_t RangeHalf = 100000.0;

const uint64_t Inf = 0xFFFFFFFFFFFFFFFFULL;

uint64_t Add(uint64_t a, uint64_t b)
{
    if (Inf - a < b)
        return a;
    return a + b;
}

uint64_t Mul(uint64_t a, uint64_t b)
{
    if (Inf / a < b)
        return a;
    return a * b;
}

bool IsOk(uint64_t n, uint64_t pow2, uint64_t p)
{
    if (pow2 * 2 < 3)
        return false;
    return Add(Mul(p, p), Mul(p, (pow2 * 2 - 3))) == 2 * n;
}

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        const double_t pow2f = (double_t)pow2;
        const double_t d = (pow2f * 2.0 - 3.0) + 8.0 * (double_t)n;
        if (IsLess(d, 0.0L))
            continue;

        for (uint64_t p = 1; p < 10; p += 2)
        {
            if (IsOk(n, pow2, p))
                ans.insert(pow2 * p);
        }

        const double_t x1f = (3.0 - pow2f + sqrt(d)) * 0.5;
        if (IsLess(x1f, 0.0L))
            continue;

        const double_t lbf = Max(x1f - RangeHalf, 0.0L);
        const double_t rbf = x1f + RangeHalf;

        const uint64_t lb = (uint64_t)lbf;
        const uint64_t rb = (uint64_t)rbf;

        for (uint64_t p = 2 * (lb / 2) + 1; p <= rb; p += 2)
        {
            if (IsOk(n, pow2, p))
            {
                ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::set<uint64_t> set_uint64_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const double_t RangeHalf = 100000.0;

const uint64_t Inf = 0xFFFFFFFFFFFFFFFFULL;

uint64_t Add(uint64_t a, uint64_t b)
{
    if (Inf - a < b)
        return Inf;
    return a + b;
}

uint64_t Mul(uint64_t a, uint64_t b)
{
    if (Inf / a < b)
        return Inf;
    return a * b;
}

double_t Sqr(double_t x)
{
    return x * x;
}

bool IsOk(uint64_t n, uint64_t pow2, uint64_t p)
{
    if (pow2 * 2 < 3)
    {
        uint64_t pp = Mul(p, p);
        pp -= p;
        return pp == 2 * n;
    }
    return Add(Mul(p, p), Mul(p, (pow2 * 2 - 3))) == 2 * n;
}

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        for (uint64_t p = 1; p < 10; p += 2)
        {
            if (IsOk(n, pow2, p))
                ans.insert(pow2 * p);
        }

        const double_t pow2f = (double_t)pow2;
        const double_t d = Sqr(pow2f * 2.0 - 3.0) + 8.0 * (double_t)n;
        if (IsLess(d, 0.0L))
            continue;

        const double_t dq = sqrt(d);
        const double_t x1f = (3.0 - 2.0 * pow2f + dq) * 0.5;
        if (IsLess(x1f, 0.0L))
            continue;

        const double_t lbf = Max(x1f - RangeHalf, 0.0L);
        const double_t rbf = x1f + RangeHalf;

        const uint64_t lb = (uint64_t)lbf;
        const uint64_t rb = (uint64_t)rbf;

        for (uint64_t p = 2 * (lb / 2) + 1; p <= rb; p += 2)
        {
            if (IsOk(n, pow2, p))
            {
                ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, false)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

#if defined(ONLINE_JUDGE)
#define LOCAL_TEST 0
#else
#define LOCAL_TEST 1
#endif

#if LOCAL_TEST
#define LOCAL_ASSERT(expr) { if (!(expr)) {std::cout << "ASSERT FAILED: '" << #expr << "'" << std::endl; _CrtDbgBreak(); } }
#else
#define LOCAL_ASSERT(expr)
#endif

typedef long double double_t;
typedef std::string string8_t;

typedef std::vector<size_t> vector_size_t;
typedef std::vector<uint64_t> vector_uint64_t;
typedef std::vector<int32_t> vector_int32_t;
typedef std::vector<vector_size_t> vector_2d_size_t;
typedef std::vector<string8_t> vector_string8_t;
typedef std::set<uint64_t> set_uint64_t;
typedef std::multiset<string8_t> multiset_string8_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}
template<typename T> inline void UpdateMin(T& a, const T b) {a = Min(a, b);}
template<typename T> inline void UpdateMax(T& a, const T b) {a = Max(a, b);}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

template<typename T> inline string8_t ToStr(const T& val) { std::ostringstream ostr; ostr << val; return ostr.str(); }
template<typename T> inline bool FromStr(const string8_t& str, T& val) {std::istringstream istr(str); istr >> val; return !!istr; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        {
            const uint64_t MaxSlow = 10;
            for (uint64_t p = 1; p < MaxSlow; p += 2)
            {
                if (p > 2 * n)
                {
                    break;
                }
                const uint64_t m = 2 * pow2 + p;
                if (m > 2 * n + 3)
                {
                    break;
                }
                if (m < 3)
                {
                    p += 2;
                    continue;
                }

                const uint64_t x = p * (m - 3);

                if (x > 2 * n)
                    break;

                if (x == 2 * n)
                    ans.insert(pow2 * p);
            }
        }

        {
            uint64_t d = 1ULL << 63;
            uint64_t pz = 0;
            while (true)
            {
                if (pz > 2*n)
                {
                    break;
                }

                const uint64_t m = 2 * pow2 + pz;
                if (m > 2 * n + 3)
                {
                    break;
                }

                if (m >= 3)
                {
                    const uint64_t x = pz * (m - 3);

                    if (x > 2 * n)
                        break;

                    if (x == 2 * n && (pz % 2 == 1))
                        ans.insert(pow2 * pz);
                }

                {
                    bool shouldAdd = true;
                    if (pz + d > 2 * n)
                    {
                        shouldAdd = false;
                    }

                    if (2 * pow2 + pz + d > 2 * n + 3)
                    {
                        shouldAdd = false;
                    }

                    if ((2 * pow2 + pz + d - 3) * (pz + d) > 2 * n)
                    {
                        shouldAdd = false;
                    }

                    if (shouldAdd)
                        pz += d;
                }
                if (d == 0)
                    break;
                d /= 2;
            }
        }
    }

    return ans;
}

set_uint64_t GetAnsSlow(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        {
            for (uint64_t p = 1; ; p += 2)
            {
                if (p > 2 * n)
                {
                    break;
                }
                const uint64_t m = 2 * pow2 + p;
                if (m > 2 * n + 3)
                {
                    break;
                }
                if (m < 3)
                {
                    p += 2;
                    continue;
                }

                const uint64_t x = p * (m - 3);

                if (x > 2 * n)
                    break;

                if (x == 2 * n)
                    ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

void Test()
{
    for (uint64_t n = 2; n <= 100000; n++)
    {
        const set_uint64_t& aRef = GetAnsSlow(n);
        const set_uint64_t& a = GetAns(n);
        LOCAL_ASSERT(a == aRef);
    }
}

int main()
{
#if LOCAL_TEST
    Test();
#endif
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::set<uint64_t> set_uint64_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const double_t RangeHalf = 100000.0;

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        const double_t pow2f = (double_t)pow2;
        const double_t d = (pow2f * 2.0 - 3.0) + 8.0 * (double_t)n;
        if (IsLess(d, 0.0L))
            continue;

        for (uint64_t p = 0; p < 10; p++)
        {
            if (p*p + p*(pow2 * 2) == 2*n)
                ans.insert(pow2 * p);
        }

        const double_t x1f = (3.0 - pow2f + sqrt(d)) * 0.5;
        if (IsLess(x1f, 0.0L))
            continue;

        const double_t lbf = Max(x1f - RangeHalf, 0.0L);
        const double_t rbf = x1f + RangeHalf;

        const uint64_t lb = (uint64_t)lbf;
        const uint64_t rb = (uint64_t)rbf;

        for (uint64_t p = 2 * (lb / 2) + 1; p <= rb; p += 2)
        {
            if (p * p + p * (pow2 * 2 - 3) == 2 * n)
            {
                ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}


#if defined(ONLINE_JUDGE)
#define _SECURE_SCL 0
#endif

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <map>
#include <functional>
#include <cmath>
#include <climits>
#include <numeric>
#include <memory.h>

#if !defined(__GNUC__)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed long int32_t;
typedef unsigned long uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#else // !defined(__GNUC__)
#define _CrtDbgBreak()
#endif // !defined(__GNUC__)

typedef long double double_t;
typedef std::set<uint64_t> set_uint64_t;

// Auxiliary functions definition
//
template<typename T> inline T Abs(const T a) { return a < 0 ? -a : a; }
template<typename T> inline T Min(const T a, const T b) {return a < b ? a : b;}
template<typename T> inline T Max(const T a, const T b) {return a > b ? a : b;}

static const double_t eps = 1.0e-09;
template<typename T> inline bool IsEqual(const T a, const T b) { return Abs(a - b) < eps; }
template<typename T> inline bool IsGreater(const T a, const T b) { return a > b + eps; }
template<typename T> inline bool IsLess(const T a, const T b) { return a + eps < b; }

#if defined(ONLINE_JUDGE)
template<size_t id> class StopWatch { };
#elif !defined(__GNUC__)
#include <library/lib_stopwatch.h>
#else
#include "../../library/library/lib_stopwatch.h"
#endif

const double_t RangeHalf = 100000.0;

const uint64_t Inf = 0xFFFFFFFFFFFFFFFFULL;

uint64_t Add(uint64_t a, uint64_t b)
{
    if (Inf - a < b)
        return a;
    return a + b;
}

uint64_t Mul(uint64_t a, uint64_t b)
{
    if (Inf / a < b)
        return a;
    return a * b;
}

bool IsOk(uint64_t n, uint64_t pow2, uint64_t p)
{
    if (pow2 * 2 < 3)
    {
        uint64_t pp = Mul(p, p);
        pp -= p;
        return pp == 2 * n;
    }
    return Add(Mul(p, p), Mul(p, (pow2 * 2 - 3))) == 2 * n;
}

set_uint64_t GetAns(const uint64_t n)
{
    set_uint64_t ans;
    for (uint64_t k = 0; k <= 62; k++)
    {
        const uint64_t pow2 = (1ULL << k);

        const double_t pow2f = (double_t)pow2;
        const double_t d = (pow2f * 2.0 - 3.0) + 8.0 * (double_t)n;
        if (IsLess(d, 0.0L))
            continue;

        for (uint64_t p = 1; p < 10; p += 2)
        {
            if (IsOk(n, pow2, p))
                ans.insert(pow2 * p);
        }

        const double_t x1f = (3.0 - pow2f + sqrt(d)) * 0.5;
        if (IsLess(x1f, 0.0L))
            continue;

        const double_t lbf = Max(x1f - RangeHalf, 0.0L);
        const double_t rbf = x1f + RangeHalf;

        const uint64_t lb = (uint64_t)lbf;
        const uint64_t rb = (uint64_t)rbf;

        for (uint64_t p = 2 * (lb / 2) + 1; p <= rb; p += 2)
        {
            if (IsOk(n, pow2, p))
            {
                ans.insert(pow2 * p);
            }
        }
    }

    return ans;
}

bool Solve(std::istream& ist, std::ostream& ost, const bool multipleTestMode)
{
    StopWatch<1> sw; sw;

    //
    uint64_t n;
    ist >> n;

    if (multipleTestMode && !ist)
        return false;

    if (n == 1)
    {
        ost << "2" << std::endl;
        return multipleTestMode;
    }

    const set_uint64_t ans = GetAns(n);

    if (ans.empty())
    {
        ost << "-1" << std::endl;
    }
    else
    {
        for (set_uint64_t::const_iterator pi = ans.begin(); pi != ans.end(); ++pi)
        {
            ost << (*pi) << std::endl;
        }
    }

    return multipleTestMode;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::istream& ist = std::cin;
    std::ostream& ost = std::cout;
#if defined(ONLINE_JUDGE)
    Solve(ist, ost, false);
#else
    while(Solve(ist, ost, true)) {};
#endif
}


#include <iostream>
#include <set>

using namespace std;

typedef long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1LL << (x+1)) - 3;

        ll a = 0, b = 1e9;
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * (mid + p) >= 2*n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if((a == b) && (a * (a+p) == 2*n) && (a & 1))
            ans.insert(a * (1LL << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}


#include <iostream>
#include <set>

using namespace std;

typedef unsigned long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1LL << x) - 1;

        ll a = 0, b = min((ll)(1.5*sqrt(double(2*n))), (p == 0) ? n : n / p);
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * p + mid * (mid - 1) / 2 >= n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if((a == b) && (mid * p + mid * (mid - 1) / 2 == n) && (a & 1))
            ans.insert(a * (1LL << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}
/*
249999998807430810
Вывод
-1
Ответ
1414213558
*/


#include <iostream>
#include <set>

using namespace std;

typedef unsigned long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1LL << (x+1)) - 3;

        ll a = 0, b = 1e9;
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * (mid + p) >= 2*n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if((a == b) && (a * (a+p) == 2*n) && (a & 1))
            ans.insert(a * (1LL << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}


#include <iostream>
#include <set>

using namespace std;

typedef unsigned long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1LL << x) - 1;

        ll a = 0, b = min((ll)(1.5*sqrt(2*n)), (p == 0) ? n : n / p);
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * p + mid * (mid - 1) / 2 >= n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if((a == b) && (mid * p + mid * (mid - 1) / 2 == n) && (a & 1))
            ans.insert(a * (1LL << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}
/*
249999998807430810
Вывод
-1
Ответ
1414213558
*/


#include <iostream>
#include <set>

using namespace std;

typedef unsigned long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1LL << x) - 1;

        ll a = 0, b = (p == 0) ? n : n / p;
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * p + mid * (mid - 1) / 2 >= n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if((a == b) && (mid * p + mid * (mid - 1) / 2 == n) && (a & 1))
            ans.insert(a * (1LL << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}


#include <iostream>
#include <set>

using namespace std;

typedef long long ll;

int main()
{
    ll n;
    cin >> n;

    set<ll> ans;

    for(ll x = 0; x <= 62; ++x) {
        ll p = (1 << (x+1)) - 3;

        ll a = 0, b = 1e9;
        ll mid = a + (b - a) / 2;

        while(a < b) {
            if(mid * (mid + p) >= 2*n) {
                b = mid;
            } else {
                a = mid + 1;
            }

            mid = a + (b - a) / 2;
        }

        if(a == b && (a * (a+p) == 2*n))
            ans.insert(a * (1 << x));
    }

    if(ans.empty()) {
        cout << -1;
    } else {
        for(set<ll>::iterator i = ans.begin(); i != ans.end(); ++i)
            cout << *i << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stack>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <complex>
using namespace std;
#define pb push_back
#define mp make_pair
#define point complex <double>
#define xx real()
#define yy imag()

set <long long> ans;
set <long long>::iterator it;

void check(long long a, long long n){
    long long l, r, k;
    l = 1;
    for(r = 1; ; r = r * 2){
        if ((2 * r - 1) * (r - 1 + a) > n){
            break;
        }
    }
    for(; l + 1 < r; ){
        k = (l + r) / 2;
        if ((2 * k - 1) * (k - 1 + a) <= n){
            l = k;
        }
        else {
            r = k;
        }
    }
    if ((2 * l - 1) * (l - 1 + a) == n){
        ans.insert((2 * l - 1) * (a + 1));
    }
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    long long n, a, k;
    cin >> n;
    for(a = 1; a - 1 <= n; a = a * 2){
        check(a - 1, n);
    }
    if (ans.size() == 0){
        cout << -1;
        return 0;
    }
    for(it = ans.begin(); it != ans.end(); it++){
        cout << (*it) << endl;
    }
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<map>
#include<queue>
#include<stdlib.h>
#include<vector>
using namespace std;
__int64 ans[100];
int main() {
	__int64 n;
	__int64 up, down, mid;
	int i, ed = 0;
	scanf("%I64d", &n);
	for (i = 0; ((1LL << i) - 1) <= n; ++i) {
		up = 1000000000;
		down = 1;
		while (up - down > 1) {
			mid = (up + down) / 2;
			if ((n - mid * (mid - 1) / 2) / mid > ((1LL << i)-1))
				down = mid;
			else
				up = mid;
		}
		if ((n - down * (down - 1) / 2) == ((1LL << i)-1) * down)
			ans[ed++] = down*(1LL<<i);
		if ((n - up * (up - 1) / 2) == ((1LL << i)-1) * up)
			ans[ed++] = up*(1LL<<i);
	}
	up=sqrt((double)n*2);
	while(1)
	{
		if(up*(up-1)/2==n)
			ans[ed++]=up;
		if(up*(up-1)/2>n)
			break;
		up++;
	}
	sort(ans,ans+ed);
	for(i=0;i<ed;++i)
	{
		if(i==0||ans[i]!=ans[i-1])
			printf("%I64d\n",ans[i]);
	}
	if(ed==0)
		puts("-1");
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<map>
#include<queue>
#include<stdlib.h>
#include<vector>
using namespace std;
__int64 ans[1000];
int main() {
    __int64 n;
    __int64 up, down, mid;
    int i, ed = 0;
    scanf("%I64d", &n);
    for (i = 0; ((1LL << i) - 1) <= n; ++i) {
        up = 10000000000;
        down = 1;
        while (up - down > 1) {
            mid = (up + down) / 2;
            if ((n - mid * (mid - 1) / 2) / mid > ((1LL << i)-1))
                down = mid;
            else
                up = mid;
        }
        if ((n - down * (down - 1) / 2) == ((1LL << i)-1) * down&&down%2==1)
            ans[ed++] = down*(1LL<<i);
        if ((n - up * (up - 1) / 2) == ((1LL << i)-1) * up&&up%2==1)
            ans[ed++] = up*(1LL<<i);
    }
    up=sqrt((double)n*2);
    while(1)
    {
        if(up*(up-1)/2==n&&up%2==1)
            ans[ed++]=up;
        if(up*(up-1)/2>n)
            break;
        up++;
    }
    sort(ans,ans+ed);
    for(i=0;i<ed;++i)
    {
        if(i==0||ans[i]!=ans[i-1])
            printf("%I64d\n",ans[i]);
    }
    if(ed==0)
        puts("-1");
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
#include<map>
#include<queue>
#include<stdlib.h>
#include<vector>
using namespace std;
__int64 ans[100];
int main() {
    __int64 n;
    __int64 up, down, mid;
    int i, ed = 0;
    scanf("%I64d", &n);
    for (i = 0; ((1LL << i) - 1) <= n; ++i) {
        up = 1000000000;
        down = 1;
        while (up - down > 1) {
            mid = (up + down) / 2;
            if ((n - mid * (mid - 1) / 2) / mid > ((1LL << i)-1))
                down = mid;
            else
                up = mid;
        }
        if ((n - down * (down - 1) / 2) == ((1LL << i)-1) * down&&down%2==1)
            ans[ed++] = down*(1LL<<i);
        if ((n - up * (up - 1) / 2) == ((1LL << i)-1) * up&&up%2==1)
            ans[ed++] = up*(1LL<<i);
    }
    up=sqrt((double)n*2);
    while(1)
    {
        if(up*(up-1)/2==n&&up%2==1)
            ans[ed++]=up;
        if(up*(up-1)/2>n)
            break;
        up++;
    }
    sort(ans,ans+ed);
    for(i=0;i<ed;++i)
    {
        if(i==0||ans[i]!=ans[i-1])
            printf("%I64d\n",ans[i]);
    }
    if(ed==0)
        puts("-1");
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;
int64 pow2[64];

int64 f(int64 v, int t)
{
    v = 2 * v + 1;
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    return res;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    pow2[0] = 1;
    for (int i = 1; i <= 62; i++)
        pow2[i] = pow2[i - 1] * 2;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = 0, rb = (int64)1e9 / pow2[i] + 100;
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (f(mb, i) < n)
                lb = mb;
            else
                rb = mb;
        }

        if (f(rb, i) == n)
            res.push_back(pow2[i - 1] * (2 * rb + 1));
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;
int64 pow2[64];

int64 f(int64 v, int t)
{
    v = 2 * v + 1;
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    return res;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    pow2[0] = 1;
    for (int i = 1; i <= 62; i++)
        pow2[i] = pow2[i - 1] * 2;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = -1, rb = (int64)1e9 / pow2[i] + 100;
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (f(mb, i) < n)
                lb = mb;
            else
                rb = mb;
        }

        if (f(rb, i) == n)
            res.push_back(pow2[i - 1] * (2 * rb + 1));
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;
int64 pow2[64];

bool ls(int64 v, int t)
{
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    return res < n;
}

bool eq(int64 v, int t)
{
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        if (v % 2 == 1)
            return false;
        v /= 2;
        res += v;
    }
    if (v % 2 == 0)
        return false;
    res += v * (v - 1) / 2;

    return res == n;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    pow2[0] = 1;
    for (int i = 1; i <= 62; i++)
        pow2[i] = pow2[i - 1] * 2;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = 0, rb = (int64)1e9 / pow2[i - 1] + 1;
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (ls(mb, i))
                lb = mb;
            else
                rb = mb;
        }

        for (int64 j = max(0LL, rb - 1000); j <= rb + 1000; j++)
            if (eq(j, i))
                res.push_back(pow2[i - 1] * j);
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;
int64 pow2[64];

int64 f(int64 v, int t)
{
    v = 2 * v + 1;
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    if (res < 0)
        return true;

    return res;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    pow2[0] = 1;
    for (int i = 1; i <= 62; i++)
        pow2[i] = pow2[i - 1] * 2;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = -1, rb = (int64)1e9 + 1;
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (f(mb, i) < n)
                lb = mb;
            else
                rb = mb;
        }

        if (f(rb, i) == n)
            res.push_back(pow2[i - 1] * (2 * rb + 1));
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;

bool ls(int64 v, int t)
{
    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    return res < n;
}

bool eq(int64 v, int t)
{
    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        if (v % 2 == 1)
            return false;
        v /= 2;
        res += v;
    }
    if (v % 2 == 0)
        return false;
    res += v * (v - 1) / 2;

    return res == n;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = 0, rb = (int64)1e9 + 1;
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (ls(mb, i))
                lb = mb;
            else
                rb = mb;
        }

        for (int64 j = max(0LL, rb - 10000); j <= rb + 10000; j++)
            if (eq(j, i))
                res.push_back(j);
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
using namespace std;

typedef long long int64;

int64 n;
vector<int64> res;
int64 pow2[64];

int64 f(int64 v, int t)
{
    v = 2 * v + 1;
    v *= pow2[t - 1];

    int64 res = 0;
    for (int i = 0; i < t - 1; i++)
    {
        v /= 2;
        res += v;
    }
    res += v * (v - 1) / 2;

    if (res < 0)
        return true;

    return res;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cin >> n;

    pow2[0] = 1;
    for (int i = 1; i <= 62; i++)
        pow2[i] = pow2[i - 1] * 2;

    for (int i = 1; i <= 62; i++)
    {
        int64 lb = -1, rb = ((int64)1e9 + pow2[i] - 1) / pow2[i];
        while (rb - lb > 1)
        {
            int64 mb = (lb + rb) / 2;
            if (f(mb, i) < n)
                lb = mb;
            else
                rb = mb;
        }

        if (f(rb, i) == n)
            res.push_back(pow2[i - 1] * (2 * rb + 1));
    }

    if (res.empty())
    {
        cout << "-1";
        return 0;
    }

    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << '\n';

    return 0;
}


//#pragma comment(linker, "/STACK:20000000")
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <ctime>

#ifndef GATILOV_INTEGER_LONG_ARITHMETICS_192768
#define GATILOV_INTEGER_LONG_ARITHMETICS_192768

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <vector>
#undef min
#undef max

#define USE_INT64

class LongInteger {
public:
    typedef LongInteger Lint;
#ifdef USE_INT64
	typedef long long int64;
	static const int DIGITS = 9;
	static const int BASE = 1000000000;
#else
	typedef int int64;
	static const int DIGITS = 4;
	static const int BASE = 10000;
#endif

	char sign;			// (-1 / 0 / 1)
	std::vector<int> arr;

    inline const int &operator[] (int ind) const { return arr[ind]; }
	inline int &operator[] (int ind) { return arr[ind]; }

	inline void CutTrailingZeros();
	inline int UnsignedCompare(const Lint &other) const;
	inline void UnsignedAdd(const Lint &base, const Lint &other);
	inline void UnsignedSub(const Lint &base, const Lint &other);
	inline void AddSub(const Lint &other, char othersign);

	inline void ShiftSub(const Lint &other, int shift);
	inline bool ShiftNotLess(const Lint &other, int shift) const;
	inline double GetDoubleApprox(int level) const;

	inline void PureMultDigit(const Lint &base, int digit);
	inline int PureDivideDigit(const Lint &base, int digit);

	template<class T> inline const T DullConverter() const;
	template<class T> inline void DullConstructor(T x);
	static int ScanDigit(const char *s, const char *t);

public:
	inline LongInteger() : sign(0), arr() {}
	inline LongInteger(const LongInteger &x) : sign(x.sign), arr(x.arr) {}
	inline LongInteger &operator= (const Lint &x) { sign = x.sign;  arr = x.arr;  return *this; }
	inline operator int() const { return DullConverter<int>(); }
	inline operator long long() const { return DullConverter<long long>(); }
	inline operator double() const { return DullConverter<double>(); }
	inline LongInteger(int x) { DullConstructor<int>(x); }
	inline LongInteger(long long x) { DullConstructor<long long>(x); }

	inline int Compare(const Lint &other) const;
	inline const Lint operator<< (int digs) const;
	inline const Lint operator>> (int digs) const;
	inline Lint &operator+= (const Lint &other) { AddSub(other,  other.sign);  return *this; }
	inline Lint &operator-= (const Lint &other) { AddSub(other, -other.sign);  return *this; }
	inline void operator++ () { *this += 1; }
	inline void operator-- () { *this -= 1; }
	inline void operator++ (int) { *this += 1; }
	inline void operator-- (int) { *this -= 1; }
	inline void Divide(const Lint &other, Lint &div, Lint &rem) const;
	inline const Lint operator* (const Lint &other) const;
	inline const Lint operator/ (const Lint &other) const { Lint div, rem;  Divide(other, div, rem);  return div; }
	inline const Lint operator% (const Lint &other) const { Lint div, rem;  Divide(other, div, rem);  return rem; }
	inline Lint &operator*= (int other);
	inline Lint &operator/= (int other);
	inline int operator% (int other) const;
	inline Lint SquareRoot() const;

	inline int GetSign() const { return sign; }
	inline Lint &Negate() { sign = -sign;   return *this; }
	inline Lint &Absolute() { if (sign < 0) sign = -sign;  return *this; }
	inline const Lint operator- () const { return Lint(*this).Negate(); }

	inline bool operator< (const Lint &other) const { return Compare(other) < 0; }
	inline bool operator> (const Lint &other) const { return Compare(other) > 0; }
	inline bool operator== (const Lint &other) const { return Compare(other) == 0; }
	inline bool operator<= (const Lint &other) const { return Compare(other) <= 0; }
	inline bool operator>= (const Lint &other) const { return Compare(other) >= 0; }
	inline bool operator!= (const Lint &other) const { return Compare(other) != 0; }
	inline Lint &operator<<= (int digs) { *this = *this << digs;  return *this; }
	inline Lint &operator>>= (int digs) { *this = *this >> digs;  return *this; }
	inline const Lint operator+ (const Lint &other) const { return Lint(*this) += other; }
	inline const Lint operator- (const Lint &other) const { return Lint(*this) -= other; }
	inline Lint &operator*= (const Lint &other) { *this = *this * other;  return *this; }
	inline Lint &operator/= (const Lint &other) { *this = *this / other;  return *this; }
	inline Lint &operator%= (const Lint &other) { *this = *this % other;  return *this; }
	inline const Lint operator* (int other) const { return Lint(*this) *= other; }
	inline const Lint operator/ (int other) const { return Lint(*this) /= other; }
	inline Lint &operator%= (int other) { *this = *this % other;  return *this; }

	inline operator std::string() const;
	inline LongInteger(const std::string &s);
	inline void Print(FILE *f = stdout) const;
	inline void Scan(FILE *f = stdin);
//	friend inline void swap(LongInteger &a, LongInteger &b);
};

namespace std {
	inline const LongInteger abs(const LongInteger &f) {
		return LongInteger(f).Absolute();
	}
	inline void swap(LongInteger &a, LongInteger &b) {
		std::swap(a.sign, b.sign);
		std::swap(a.arr, b.arr);
	}
};

//Implementation
inline const LongInteger LongInteger::operator<< (int digs) const {
	assert(digs >= 0);
	if (sign == 0) return Lint();
	Lint res;
	res.sign = sign;
	res.arr.resize(arr.size() + digs);
	int i;
	for (i = res.arr.size()-1; i-digs>=0; i--) res.arr[i] = arr[i-digs];
	for (; i>=0; i--) res.arr[i] = 0;
	return res;
}

inline const LongInteger LongInteger::operator>> (int digs) const {
	assert(digs >= 0);
	if (sign == 0 || arr.size() < digs) return Lint();
	Lint res;
	res.sign = sign;
	res.arr.resize(arr.size() - digs);
	int i;
	for (i = 0; i<res.arr.size(); i++) res.arr[i] = arr[i+digs];
	return res;
}

inline void LongInteger::CutTrailingZeros() {
	while (arr.size() && !arr.back()) arr.pop_back();
	if (arr.empty()) sign = 0;
}

inline int LongInteger::UnsignedCompare(const Lint &other) const {
	if (arr.size() != other.arr.size()) return (arr.size() < other.arr.size() ? -1 : 1);
	for (int i = arr.size()-1; i>=0; i--)
		if (arr[i] != other[i])
			return (arr[i] < other[i] ? -1 : 1);
	return 0;
}

inline void LongInteger::UnsignedAdd(const Lint &base, const Lint &other) {
	int buff = 0;
	int sz = std::max(base.arr.size(), other.arr.size());
	arr.resize(sz);
	for (int i = 0; i<sz; i++) {
		arr[i] = (i<base.arr.size() ? base[i] : 0) + (i<other.arr.size() ? other[i] : 0) + buff;
		if (arr[i] >= BASE) {
			arr[i] -= BASE;
			buff = 1;
		}
		else buff = 0;
	}
	if (buff) arr.push_back(buff);
}

inline void LongInteger::UnsignedSub(const Lint &base, const Lint &other) {
	int buff = 0;
	assert(base.arr.size() >= other.arr.size());
	int sz = base.arr.size();
	arr.resize(sz);
	for (int i = 0; i<sz; i++) {
		arr[i] = base[i] - (i<other.arr.size() ? other[i] : 0) - buff;
		if (arr[i] < 0) {
			arr[i] += BASE;
			buff = 1;
		}
		else buff = 0;
	}
	assert(!buff);
	CutTrailingZeros();
}

inline void LongInteger::AddSub(const Lint &other, char othersign) {
	if (othersign == 0) return;
	if (sign == 0) {
		*this = other;
		sign = othersign;
		return;
	}
	if (sign == othersign) {
		UnsignedAdd(*this, other);
		return;
	}
	int t = UnsignedCompare(other);
	if (t==0) { *this = 0;  arr.clear(); }
	else {
		if (t>0) UnsignedSub(*this, other);
		else {
			UnsignedSub(other, *this);
			sign = othersign;
		}
	}
}

inline void LongInteger::PureMultDigit(const Lint &base, int digit) {
	int64 buff = 0;
	int sz = base.arr.size();
	arr.resize(sz + 1);
	for (int i = 0; i<sz; i++) {
		buff += int64(base[i]) * digit;
		arr[i] = buff % BASE;
		buff /= BASE;
	}
	arr[sz] = buff;
	CutTrailingZeros();
}

inline int LongInteger::PureDivideDigit(const Lint &base, int digit) {
	assert(digit);
	int64 buff = 0;
	arr.resize(base.arr.size());
	for (int i = base.arr.size()-1; i>=0; i--) {
		buff *= BASE;
		buff += base[i];
		arr[i] = buff / digit;
		buff %= digit;
	}
	CutTrailingZeros();
	return buff;
}

inline LongInteger &LongInteger::operator*= (int other) {
	int sgn = (other ? (other<0 ? -1 : 1) : 0);
	sign *= sgn;
	if (sign == 0) return *this;
	other *= sgn;
	if (other < BASE) PureMultDigit(*this, other);
	else *this *= Lint(other);
	return *this;
}

inline LongInteger &LongInteger::operator/= (int other) {
	int sgn = (other ? (other<0 ? -1 : 1) : 0);
	assert(sgn);
	sign *= sgn;
	if (sign == 0) return *this;
	other *= sgn;
	if (other < BASE) PureDivideDigit(*this, other);
	else *this /= Lint(other);
	return *this;
}

inline int LongInteger::operator% (int other) const {
	int sgn = (other ? (other<0 ? -1 : 1) : 0);
	assert(sgn);
	if (sign == 0) return 0;
	other *= sgn;
	if (other < BASE) {
		Lint temp;
		return sign * temp.PureDivideDigit(*this, other);
	}
	else {
		other *= sgn;
		return *this % Lint(other);
	}
}

inline const LongInteger LongInteger::operator* (const Lint &other) const {
	static const int TIMES = 9;
	Lint res;
	res.sign = sign * other.sign;
	if (res.sign == 0) return res;

	int tsz = arr.size();
	int osz = other.arr.size();
	int rsz = tsz + osz;
	res.arr.resize(rsz);

	int64 buff, mega;
	mega = 0;
	for (int i = 0; i<rsz; i++) {
		int cnt = 0;
		buff = mega;
		mega = 0;
		for (int j = std::max(0, i-osz+1); j<=std::min(i, tsz-1); j++) {
			buff += int64(arr[j]) * other[i-j];
			if ((++cnt) == TIMES) {
				mega += buff / BASE;
				buff %= BASE;
				cnt = 0;
			}
		}
		mega += buff / BASE;
		res.arr[i] = buff % BASE;
	}
	assert(mega == 0);
	res.CutTrailingZeros();
	return res;
}

inline bool LongInteger::ShiftNotLess(const Lint &other, int shift) const {
	if (arr.size() != other.arr.size() + shift) return (arr.size() >= other.arr.size() + shift);
	for (int i = arr.size()-1; i>=shift; i--)
		if (arr[i] != other[i-shift])
			return arr[i] >= other[i-shift];
	return true;
}
inline void LongInteger::ShiftSub(const Lint &other, int shift) {
	int buff = 0;
	assert(other.sign == 0 || arr.size() >= other.arr.size() + shift);
	int sz = arr.size();
	for (int i = shift; i<sz; i++) {
		arr[i] -= (i-shift < other.arr.size() ? other[i-shift] : 0) + buff;
		if (arr[i] < 0) {
			arr[i] += BASE;
			buff = 1;
		}
		else buff = 0;
	}
	assert(!buff);
	CutTrailingZeros();
}
/*inline void LongInteger::Divide(const Lint &other, Lint &div, Lint &rem) const {		//variant with binary search
	assert(other.sign);
	int tsz = arr.size();
	int osz = other.arr.size();
	if (sign == 0 || tsz < osz) {
		div = Lint();	//zero
		rem = *this;
		return;
	}

	div.arr.resize(tsz - osz + 1);
	Lint ost = *this;
	for (int i = tsz - osz; i>=0; i--) {
		int left = 0;
		int right = BASE;
		int middle;
		Lint tmult;
		while (right - left > 1) {
			middle = (left + right) >> 1;
			Lint tmult;
			tmult.PureMultDigit(other, middle);
			if (ost.ShiftNotLess(tmult, i)) left = middle;
			else right = middle;
		}
		div[i] = left;
		tmult.PureMultDigit(other, left);
		ost.ShiftSub(tmult, i);
	}
	rem = ost;

	div.sign = sign * other.sign;
	rem.sign = sign;
	div.CutTrailingZeros();
	rem.CutTrailingZeros();
}*/
inline double LongInteger::GetDoubleApprox(int level) const {
	double res = 0.0;
	for (int j = arr.size() - 1; j>=level; j--) {
		res *= BASE;
		if (j >= 0) res += arr[j];
	}
	return res;
}
inline void LongInteger::Divide(const Lint &other, Lint &div, Lint &rem) const {
	static const double EPS = std::max(3.0 / BASE, 1e-15 * BASE);
	assert(other.sign);
	int tsz = arr.size();
	int osz = other.arr.size();
	if (sign == 0 || tsz < osz) {
		div = Lint();	//zero
		rem = *this;
		return;
	}

	div.arr.resize(tsz - osz + 1);
	Lint ost = *this;
	double dother = other.GetDoubleApprox(osz - 3);
	for (int i = tsz - osz; i>=0; i--) {
		double dcurr = ost.GetDoubleApprox(i + osz - 3) / dother;
		int curr = int(dcurr);
		double diff = dcurr - curr;

		bool canbeless = (diff<EPS && curr>0);
		bool canbegreater = (diff>1.0-EPS && curr<BASE-1);

		Lint tmult;
		tmult.sign = 1;
		if (canbegreater) curr++;
		tmult.PureMultDigit(other, curr);
		if ((canbegreater || canbeless) && !ost.ShiftNotLess(tmult, i)) {
			curr--;
			tmult.UnsignedSub(tmult, other);
		}
		div[i] = curr;
		ost.ShiftSub(tmult, i);
	}
	rem = ost;

	div.sign = sign * other.sign;
	rem.sign = sign;
	div.CutTrailingZeros();
	rem.CutTrailingZeros();
}

inline LongInteger LongInteger::SquareRoot() const {
	static const int LOGBASE2 = int(log(double(BASE))/log(2.0) / 2) + 1;
	assert(sign >= 0);
	if (sign == 0) return Lint();
	Lint left, right, middle;
	Lint lsqr, rsqr, msqr, prod;
	int power = arr.size() + 1;
	right = 1;
	for (int i = 0; i<power; i++) right *= (1<<LOGBASE2);
	rsqr = right*right;
	while (right - left > Lint(1)) {
		middle = (left + right) / 2;
		msqr = (lsqr + prod + rsqr) / 4;
		if (*this < msqr) {
			right = middle;
			rsqr = msqr;
			prod /= 2;
			prod += lsqr;
		}
		else {
			left = middle;
			lsqr = msqr;
			prod /= 2;
			prod += rsqr;
		}
	}
	return left;
}

inline int LongInteger::Compare(const Lint &other) const {
	if (sign != other.sign) return (sign < other.sign ? -1 : 1);
	if (sign == 0) return 0;
	return sign * UnsignedCompare(other);
}

template<class T> inline const T LongInteger::DullConverter() const {
	T res = 0;
	if (sign == 0) return res;
	for (int i = arr.size()-1; i>=0; i--) {
		res *= BASE;
		res += arr[i];
	}
	return res * sign;
}

template<class T> inline void LongInteger::DullConstructor(T x) {
	if (x == T(0)) { sign = 0;  return; }
	if (x < T(0)) {
		sign = -1;
		x = -x;
	}
	else sign = 1;

	if (x < T(BASE)) arr.push_back(x);
	else {
		while (x != T(0)) {
			arr.push_back(x % BASE);
			x /= BASE;
		}
	}
}

inline LongInteger::operator std::string() const {
	if (sign == 0) return "0";
	std::string res;
	char buff[32];
	if (sign < 0) res += "-";
    sprintf(buff, "%d", arr.back());
    res += buff;

    char mask[] = "%00d";  mask[2] += DIGITS;
    for (int i = arr.size() - 2; i>=0; i--) {
		sprintf(buff, mask, arr[i]);
		res += buff;
    }
    return res;
}

int LongInteger::ScanDigit(const char *s, const char *t) {
	int l = t-s;
	int res = 0;
	for (int i = 0; i<l; i++) {
		res *= 10;
		res += (s[i]-'0');
	}
	return res;
}
inline LongInteger::LongInteger(const std::string &s) {
	const char *str = s.c_str();
	int curr = 0;
	if (str[curr] == '-') {
		sign = -1;
		curr++;
	}
	else sign = 1;

	int digits = (s.size() - curr - 1) / DIGITS;
	int first = (s.size() - curr - 1) % DIGITS + 1;
	arr.resize(digits + 1);
	arr[digits] = ScanDigit(str + curr, str + curr+first);
	curr += first;
	for (int i = digits-1; i>=0; i--) {
		arr[i] = ScanDigit(str + curr, str + curr + DIGITS);
		curr += DIGITS;
	}
	assert(curr == s.size());
	CutTrailingZeros();
}

inline void LongInteger::Print(FILE *f) const {
	std::string s = std::string(*this);
	fprintf(f, "%s\n", s.c_str());
}

inline void LongInteger::Scan(FILE *f) {
	std::string str;
	fscanf(f, " ");
	int curr;
	while (1) {
		curr = fgetc(f);
		if (curr == EOF) break;
		if (isspace(curr)) {
			ungetc(curr, f);
			break;
		}
		str += curr;
	}
	*this = Lint(str);
}

#endif

using namespace std;
typedef long long int64;
#ifdef HOME
	#define E(c) cerr<<#c
	#define Eo(x) cerr<<#x<<" = "<<(x)<<endl
	#define Ef(...) fprintf(stderr, __VA_ARGS__)
#else
	#define E(c) ((void)0)
	#define Eo(x) ((void)0)
	#define Ef(...) ((void)0)
#endif

LongInteger n;
set<LongInteger> ans;

void TryAnswer(int s, LongInteger m) {
	if (m < LongInteger(1)) return;
	if (m % 2 == 0) return;
	LongInteger res = (m * (m - LongInteger(1))/2) + m * LongInteger((1LL<<s) - 1);
	if (res != n) return;
	ans.insert(LongInteger(1LL<<s) * m);
}

int main() {
#ifdef HOME
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int64 n64;
	scanf("%I64d", &n64);
	n = n64;

	for (int s = 0; s<=61; s++) {
		LongInteger qb = (1LL<<(s+1)) - 3;
		LongInteger qc = n * (-2);
		LongInteger qd = qb*qb - qc*4;
		if (qd < LongInteger(0))
			continue;
		qd = qd.SquareRoot();
		TryAnswer(s, (-qb + qd) / 2);
		TryAnswer(s, (-qb - qd) / 2);
	}

	if (ans.empty()) printf("-1\n");
	else {
		for (auto it = ans.begin(); it != ans.end(); it++)
			printf("%s\n", string(*it).c_str());
	}

	return 0;
}