Problem: Yaroslav, Andrey and Roman love playing cubes. Sometimes they get together and play cubes for hours and hours! 

Today they got together again and they are playing cubes. Yaroslav took unit cubes and composed them into an a × a × a cube, Andrey made a b × b × b cube and Roman made a c × c × c cube. After that the game was finished and the guys left. But later, Vitaly entered the room. He saw the cubes and wanted to make a cube as well. But what size should the cube be? Of course it should be a large cube with the side of length a + b + c. Besides, Vitaly decided to decompose the cubes built by Yaroslav, Andrey and Roman and compose his own large cube out of them. However, it turned out that the unit cubes he got from destroying the three cubes just weren't enough to make a large cube. We know that Vitaly was short of exactly n cubes. Vitaly got upset, demolished everything and left. As he was leaving, he met Petya and told him that there had been three cubes in the room and that he needed another n unit cubes to make his own large cube.

Petya entered the room and saw the messily scattered cubes. He wanted to make it neat and orderly again. But he only knows that there had been three cubes, made of small unit cubes and that Vitaly needed n more unit cubes to make a large one! Help Petya understand, how many ways of sizes a, b, c are there to restore Yaroslav's, Andrey's and Roman's cubes.

Input

The single line of the input contains integer n (1 ≤ n ≤ 1014). We know that all numbers a, b, c are positive integers.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Output

In the single line print the required number of ways. If it turns out that there isn't a single way of suitable sizes of a, b, c, print 0. 

Examples

Input

24


Output

1


Input

648


Output

7


Input

5


Output

0


Input

93163582512000


Output

39090

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T LOW_BIT(T n);
template <class T>
inline int COUNT_BIT(T n);
template <class T>
inline T GCD(T a, T b);
template <class T>
inline T LCM(T a, T b);
bool isUpperCase(char c);
bool isLowerCase(char c);
bool isLetter(char c);
bool isDigit(char c);
char toLowerCase(char c);
char toUpperCase(char c);
template <class T>
string toString(T n);
template <class T>
void stoa(const string &s, int &n, T A[]);
template <class T>
void atos(int n, T A[], string &s);
template <class T>
void atov(int n, T A[], vector<T> &vi);
template <class T>
void vtoa(const vector<T> &vi, int &n, T A[]);
template <class T>
void stov(const string &s, vector<T> &vi);
template <class T>
void vtos(const vector<T> &vi, string &s);
template <class T>
inline vector<pair<T, int> > factorize(T n);
int64_t inverse_mod(int64_t a, int64_t mod);
string testCaseOutTemp = "Case #%d: ";
int numThread = 4;
void initProgram() {}
int64_t fast_pow(int64_t a, int64_t n) {
  if (n == 0) return 1ll;
  if (n & 1LL) {
    return a * fast_pow(a, n - 1);
  } else {
    int64_t t = fast_pow(a, n / 2);
    return t * t;
  }
}
class Task {
 public:
  ostringstream out;
  int testcase;
  int64_t n;
  void readInput() { cin >> n; }
  int64_t p[100];
  int64_t mp[100];
  int np;
  int total;
  set<pair<int64_t, pair<int64_t, int64_t> > > res;
  void giai(int64_t x1, int64_t x2, int64_t x3) {
    int64_t t = x1 - x3 + x2;
    int64_t a, b, c;
    if (t > 0 && t % 2 == 0) {
      b = t / 2;
    } else {
      return;
    }
    t = x3 - x2 + x1;
    if (t > 0 && t % 2 == 0) {
      a = t / 2;
    } else {
      return;
    }
    t = x2 - x1 + x3;
    if (t > 0 && t % 2 == 0) {
      c = t / 2;
    } else {
      return;
    }
    res.insert(pair<int64_t, pair<int64_t, int64_t> >(
        a, pair<int64_t, int64_t>(b, c)));
  }
  int d[100];
  void duyet2(int64_t x1, int64_t x2, int id, int m2, int m1) {
    if (id >= np) return;
    for (int i = 0, __e__ = (int)(mp[id] - d[id] + 1); i < __e__; ++i)
      if (m2 + m1 + i < total) {
        int64_t temp = x2 * fast_pow(p[id], i);
        if (temp <= n / x1 / temp) {
          if (m2 + i > 0) giai(x1, temp, n / x1 / temp);
          duyet2(x1, temp, id + 1, m2 + i, m1);
        }
      }
  }
  void duyet1(int64_t x1, int id, int m1) {
    if (id >= np) {
      return;
    }
    for (int i = 0, __e__ = (int)(mp[id] + 1); i < __e__; ++i)
      if (m1 + i <= total - 2) {
        d[id] = i;
        int64_t temp = x1 * fast_pow(p[id], i);
        if (((temp) * (temp)) >= (n / temp)) {
          if (m1 + i > 0) {
            duyet2(temp, 1, 0, 0, m1 + i);
          }
        }
        duyet1(temp, id + 1, m1 + i);
      }
  }
  int64_t check(int64_t a, int64_t b, int64_t c) {
    return ((a) * (a)) * a + ((b) * (b)) * b + ((c) * (c)) * c + 3LL * n -
           ((a + b + c) * (a + b + c)) * (a + b + c);
  }
  void process() {
    if (n % 3ll != 0) {
      out << 0;
      return;
    }
    n /= 3;
    if (n < 8) {
      out << 0;
      return;
    }
    vector<pair<int64_t, int> > v = factorize(n);
    sort((v).begin(), (v).end(), greater<pair<int64_t, int> >());
    np = 0;
    total = 0;
    for (__typeof(v.begin()) it = (v.begin()), __e__ = (v.end()); it != __e__;
         ++it) {
      p[np] = it->first;
      mp[np++] = it->second;
      total += it->second;
    }
    if (total < 3) {
      out << 0;
      return;
    }
    memset(d, 0, sizeof d);
    duyet1(1, 0, 0);
    cerr << "duyet xong " << total << endl;
    set<pair<int64_t, pair<int64_t, int64_t> > > r2 = res;
    int a[3];
    for (__typeof(res.begin()) it = (res.begin()), __e__ = (res.end());
         it != __e__; ++it) {
      a[0] = it->first;
      a[1] = it->second.first;
      a[2] = it->second.second;
      sort(a, a + 3);
      pair<int64_t, pair<int64_t, int64_t> > p(
          a[0], pair<int64_t, int64_t>(a[1], a[2]));
      r2.insert(p);
      while (next_permutation(a, a + 3)) {
        pair<int64_t, pair<int64_t, int64_t> > p(
            a[0], pair<int64_t, int64_t>(a[1], a[2]));
        r2.insert(p);
      }
    }
    out << r2.size();
  }
};
int main() {
  srand(time(0));
  initProgram();
  int ntest = 1;
  {} {
    for (int i = 0, __e__ = (int)(ntest); i < __e__; ++i) {
      cerr << "processing test: " << i + 1 << endl;
      Task *pT = new Task();
      pT->testcase = i + 1;
      pT->readInput();
      pT->process();
      cout << pT->out.str();
      delete pT;
    }
  }
}
template <class T>
inline T LOW_BIT(T n) {
  return (n ^ (n - 1)) & n;
}
template <class T>
inline int COUNT_BIT(T n) {
  return (n == 0) ? 0 : (1 + COUNT_BIT(n & (n - 1)));
}
template <class T>
inline T GCD(T a, T b) {
  if (a < 0) return GCD(-a, b);
  if (b < 0) return GCD(a, -b);
  return (b == 0) ? a : GCD(b, a % b);
}
template <class T>
inline T LCM(T a, T b) {
  if (a < 0) return LCM(-a, b);
  if (b < 0) return LCM(a, -b);
  return a * (b / GCD(a, b));
}
bool isUpperCase(char c) { return c >= 'A' && c <= 'Z'; }
bool isLowerCase(char c) { return c >= 'a' && c <= 'z'; }
bool isLetter(char c) {
  return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
bool isDigit(char c) { return c >= '0' && c <= '9'; }
char toLowerCase(char c) { return (isUpperCase(c)) ? (c + 32) : c; }
char toUpperCase(char c) { return (isLowerCase(c)) ? (c - 32) : c; }
template <class T>
string toString(T n) {
  ostringstream ost;
  ost << n;
  ost.flush();
  return ost.str();
}
template <class T>
inline vector<pair<T, int> > factorize(T n) {
  vector<pair<T, int> > R;
  for (T i = 2; n > 1;) {
    if (n % i == 0) {
      int C = 0;
      for (; n % i == 0; C++, n /= i)
        ;
      R.push_back(make_pair(i, C));
    }
    i++;
    if (i > n / i) i = n;
  }
  if (n > 1) R.push_back(make_pair(n, 1));
  return R;
}
template <class T>
void stoa(const string &s, int &n, T A[]) {
  n = 0;
  istringstream sin(s);
  for (T v; sin >> v; A[n++] = v)
    ;
}
template <class T>
void atos(int n, T A[], string &s) {
  ostringstream sout;
  for (int i = 0; i < n; i++) {
    if (i > 0) sout << ' ';
    sout << A[i];
  }
  s = sout.str();
}
template <class T>
void atov(int n, T A[], vector<T> &vi) {
  vi.clear();
  for (int i = 0; i < n; i++) vi.push_back(A[i]);
}
template <class T>
void vtoa(const vector<T> &vi, int &n, T A[]) {
  n = vi.size();
  for (int i = 0; i < n; i++) A[i] = vi[i];
}
template <class T>
void stov(const string &s, vector<T> &vi) {
  vi.clear();
  istringstream sin(s);
  for (T v; sin >> v; vi.push_bakc(v))
    ;
}
template <class T>
void vtos(const vector<T> &vi, string &s) {
  ostringstream sout;
  for (int i = 0; i < vi.size(); i++) {
    if (i > 0) sout << ' ';
    sout << vi[i];
  }
  s = sout.str();
}
struct extended_gcd_res {
  int64_t x;
  int64_t y;
  extended_gcd_res(int64_t _x, int64_t _y) {
    x = _x;
    y = _y;
  }
};
extended_gcd_res extended_gcd(int64_t a, int64_t b) {
  if (b == 0)
    return extended_gcd_res(1, 0);
  else {
    int64_t q = a / b;
    int64_t r = a - b * q;
    extended_gcd_res res = extended_gcd(b, r);
    return extended_gcd_res(res.y, res.x - q * res.y);
  }
}
int64_t inverse_mod(int64_t a, int64_t mod) {
  extended_gcd_res res = extended_gcd(mod, a);
  if (res.y < 0) res.y += mod;
  return res.y;
}