#include <bits/stdc++.h>
using namespace std;
map<long long, vector<long long>> g;
map<long long, bool> g_visited;
map<long long, long long> g_parient;
map<long long, long long> g_distance;
void dfs(long long s) {
  g_visited[s] = true;
  for (auto x : g[s])
    if (!g_visited.count(x)) dfs(x);
}
long long dijkitras(long long s, long long e) {
  priority_queue<pair<long long, long long>> ss;
  ss.push({0, s});
  g_distance[s] = 0;
  g_parient[s] = -1;
  long long ans = -1;
  while (!ss.empty()) {
    auto x = ss.top();
    ss.pop();
    long long d = -x.first, ver = x.second;
    if (ver == e) {
      ans = d;
      break;
    }
    for (auto a : g[ver])
      if (!g_distance.count(a) or g_distance[a] > 1 + g_distance[ver]) {
        ss.push({-(d + 1), a});
        g_distance[a] = d + 1;
        g_parient[a] = ver;
      }
  }
  return ans;
}
vector<long long> g_dijkistra_traversal(long long s, long long e) {
  long long a = e;
  vector<long long> v;
  while (a != s) {
    v.push_back(a);
    a = g_parient[a];
  }
  v.push_back(a);
  long long g_n = v.size();
  for (long long i = v.size() / 2; i >= 0; i--) swap(v[i], v[g_n - 1 - i]);
  return v;
}
const long long INF = 0x3f3f3f3f3f3f3f3fll;
long long euclid(long long a, long long b) {
  if (b == 0) return a;
  return euclid(b, a % b);
}
tuple<long long, long long, long long> euclidian_theorem(long long a,
                                                         long long b) {
  if (b == 0) {
    return {a, 1, 0};
  }
  long long g, x, y;
  tie(g, x, y) = euclidian_theorem(b, a % b);
  return {g, y, x - ((a * y) / b)};
}
pair<long long, long long> diophentane(long long a, long long b, long long c) {
  long long g = euclid(a, b);
  long long x, y;
  if (c % g != 0) return {0, 0};
  tie(g, x, y) = euclidian_theorem(a, b);
  long long k = c / g;
  x = x * k;
  y = y * k;
  return {x, y};
}
long long modulo_inverse(long long a, long long m) {
  long long g, x, y;
  tie(g, x, y) = euclidian_theorem(a, m);
  if (g != 1) return 0;
  x = (x % m + m) % m;
  return x;
}
long long chinese_remainder_theorem(vector<long long> a, vector<long long> m) {
  long long ans = 0;
  long long n = m.size();
  for (long long i = 0; i < n; ++i)
    for (long long j = i + 1; j < n; ++j)
      if (euclid(m[i], m[j]) != 1) return 0;
  long long mul_m = 1;
  for (int i = 0; i < n; ++i) mul_m *= m[i];
  for (long long i = 0; i < n; i++) {
    long long mk = mul_m / m[i];
    long long xk = a[i] * mk * modulo_inverse(mk, m[i]);
    ans += xk;
  }
  return ans % mul_m;
}
bool prime[1000006];
void SieveOfEratosthenes(long long n = 1000005) {
  memset(prime, true, sizeof(prime));
  for (long long p = 2; p * p <= n; p++) {
    if (prime[p] == true) {
      for (long long i = p * p; i <= n; i += p) prime[i] = false;
    }
  }
}
long long xpow(long long n, long long p) {
  if (p == 0) return 1;
  long long aa = xpow(n, p / 2);
  aa = aa * aa % 1000000007;
  aa %= 1000000007;
  if (p & 1) return aa * n % 1000000007;
  return aa % 1000000007;
}
void solve() {
  long long arr[100005] = {};
  set<long long> s;
  long long n;
  cin >> n;
  for (long long i = 1; i <= 100000; i++) {
    arr[i] = arr[i - 1] + i;
    s.insert(arr[i]);
    if (arr[i] > n) break;
  }
  for (long long i = 1; i <= 100000; i++) {
    if (arr[i] > n) break;
    if (s.count(n - arr[i])) {
      cout << "YES";
      return;
    }
  }
  cout << "NO";
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  srand(time(NULL));
  solve();
  return 0;
}
