Problem: As you very well know, this year's funkiest numbers are so called triangular numbers (that is, integers that are representable as <image>, where k is some positive integer), and the coolest numbers are those that are representable as a sum of two triangular numbers.

A well-known hipster Andrew adores everything funky and cool but unfortunately, he isn't good at maths. Given number n, help him define whether this number can be represented by a sum of two triangular numbers (not necessarily different)!

Input

The first input line contains an integer n (1 ≤ n ≤ 109).

Output

Print "YES" (without the quotes), if n can be represented as a sum of two triangular numbers, otherwise print "NO" (without the quotes).

Examples

Input

256


Output

YES


Input

512


Output

NO

Note

In the first sample number <image>.

In the second sample number 512 can not be represented as a sum of two triangular numbers.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const long long sizee = 0;
int dirX[] = {0, -1, 0, 1, -1, 1, -1, 1};
int dirY[] = {-1, 0, 1, 0, 1, -1, -1, 1};
long long fact[sizee];
long long inv[sizee];
long long arr[sizee];
long long primes[sizee];
long long modPower(long long b, long long p) {
  if (p == 0) return 1;
  long long halfpow = modPower(b, p / 2);
  long long toReturn = (halfpow * halfpow) % mod;
  if (p % 2) toReturn = (toReturn * b) % mod;
  return toReturn;
}
long long fastPower(long long b, long long p) {
  if (p == 0) return 1;
  long long ans = fastPower(b, p / 2);
  ans = (ans * ans);
  if (p % 2 != 0) ans = (ans * b);
  return ans;
}
double bigPower(double a, int n) {
  double x = a, ret = 1;
  while (n) {
    int currentBit = n & 1;
    if (currentBit) ret *= x;
    x *= x;
    n = n >> 1;
  }
  return ret;
}
long long GcdRecursive(long long a, long long b) {
  if (b == 0) return a;
  return GcdRecursive(b, a % b);
}
long long modLCM(long long a, long long b) {
  long long val = GcdRecursive(a, b);
  long long tmp = ((a % mod) * (b % mod)) % mod;
  long long finalVal = ((tmp % mod) * (arr[val] % mod)) % mod;
  return finalVal;
}
long long LCM(long long a, long long b) { return (a * b) / GcdRecursive(a, b); }
void move1step(long long& a, long long& b, long long q) {
  long long c = a - q * b;
  a = b;
  b = c;
}
long long GcdIterative(long long a, long long b) {
  while (b) move1step(a, b, a / b);
  return a;
}
void pre(long long n) {
  fact[0] = 1;
  inv[0] = 1;
  for (long long i = 1; i <= n; i++) {
    fact[i] = (i * fact[i - 1]) % mod;
    inv[i] = modPower(fact[i], mod - 2);
    arr[i] = modPower(i, mod - 2);
  }
}
long long npr(long long n, long long r) {
  return ((fact[n] * inv[n - r]) % mod);
}
long long ncr(long long n, long long r) {
  return ((((fact[n] * inv[n - r]) % mod) * inv[r]) % mod);
}
void sieve(long long val) {
  memset(primes, 1, sizeof primes);
  primes[0] = primes[1] = false;
  for (int i = 2; i * i <= val; i++) {
    if (primes[i]) {
      for (int j = i * i; j <= val; j += i) {
        primes[j] = 0;
      }
    }
  }
}
long long power(long long b, long long e) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b, e / 2);
  return power(b * b, e / 2);
}
bool isPrime(long long n) {
  if (n <= 1) return false;
  for (int i = 2; i * i <= n; i++)
    if (n % i == 0) return false;
  return true;
}
string findSmallestLexoWithoutDupilcates(string s) {
  int cnt[27];
  bool vis[27];
  for (int i = 0; i < s.size(); i++) cnt[s[i] - 'a']++;
  string ans = "";
  for (int i = 0; i < s.size(); i++) {
    int x = s[i] - 'a';
    cnt[x]--;
    if (vis[x]) continue;
    while (ans.size() > 0 && s[i] < ans.back() && cnt[ans.back() - 'a'] > 0) {
      vis[ans.back() - 'a'] = false;
      ans.pop_back();
    }
    ans.push_back(s[i]);
    vis[x] = true;
  }
  return ans;
}
long double dot(complex<long double> a, complex<long double> b) {
  return (conj(a) * b).real();
}
long double cross(complex<long double> a, complex<long double> b) {
  return (conj(a) * b).imag();
}
long double angleBetVec(complex<long double> a, complex<long double> b) {
  long double d = dot(a, b);
  d /= abs(a);
  d /= abs(b);
  return acos(d) * 180 / acos(-1);
}
complex<long double> RotateAbout(complex<long double> a,
                                 complex<long double> about,
                                 long double angle) {
  return (a - about) * polar((long double)1.0, angle) + about;
}
vector<int> topological_sort(const vector<vector<int>>& adj) {
  int n = int(adj.size());
  vector<int> in_degree(n, 0);
  vector<int> order;
  for (int i = 0; i < n; i++)
    for (int neighbor : adj[i]) in_degree[neighbor]++;
  for (int i = 0; i < n; i++)
    if (in_degree[i] == 0) order.push_back(i);
  int current = 0;
  while (current < int(order.size())) {
    int node = order[current++];
    for (int neighbor : adj[node])
      if (--in_degree[neighbor] == 0) order.push_back(neighbor);
  }
  return order;
}
set<long long> GetDivisors(long long val) {
  set<long long> st;
  for (long long i = 1; i < sqrt(val) + 1; i++)
    if (val % i == 0) st.insert(i), st.insert(val / i);
  return st;
}
void LoopDiagonally(int a, int b) {
  for (int k = 0; k <= a + b - 2; k++) {
    string t = "";
    for (int j = 0; j <= k; j++) {
      int i = k - j;
      if (i < a && j < b) {
      }
    }
  }
  for (int k = 0; k <= a + b - 2; k++) {
    string t = "";
    for (int j = 0; j <= k; j++) {
      int i = a - (k - j);
      if (i >= 0 && i < a && j < b) {
      }
    }
  }
}
int getBits(int val) {
  int ctr = 0;
  while (val) {
    ctr += val & 1;
    val >>= 1;
  }
  return ctr;
}
void GetLongestSubSequenceNSquared() {}
void DSUfunctions() {}
long double pointToLine(long double x, long double y, long double x1,
                        long double y1, long double x2, long double y2) {
  long double A = x - x1;
  long double B = y - y1;
  long double C = x2 - x1;
  long double D = y2 - y1;
  long double dot = A * C + B * D;
  long double len_sq = C * C + D * D;
  long double param = -1;
  if (len_sq != 0) param = dot / len_sq;
  long double xx, yy;
  if (param < 0) {
    xx = x1;
    yy = y1;
  } else if (param > 1) {
    xx = x2;
    yy = y2;
  } else {
    xx = x1 + param * C;
    yy = y1 + param * D;
  }
  long double dx = x - xx;
  long double dy = y - yy;
  return sqrt(dx * dx + dy * dy);
}
const int N = 1e6 + 7;
const long long llinf = INT64_MAX;
const int intinf = INT32_MAX;
const int infClr = 0x3f3f3f3f;
long long t;
long long n, k, m, a, b, r, d, x, y, q, z, f, l, p;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  ;
  cin >> n;
  set<long long> s;
  for (long long i = 1; i < 1e5; i++)
    s.insert((long long)i * ((long long)i + 1) / 2);
  for (long long i = 1; i < 1e5; i++) {
    long long cur = (long long)i * ((long long)i + 1) / 2;
    if (s.count(n - cur)) return cout << "YES", 0;
  }
  cout << "NO";
}