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 JAVA):

Solution:
import java.util.*;
import java.io.*;
import java.math.BigInteger;
public class C121A{
    static BufferedReader br;
    public static void main(String args[])throws Exception{
        br=new BufferedReader(new InputStreamReader(System.in));
        long n=toLong();
        long s=(long)Math.sqrt(n)+1;
        long nums[]=new long[50000];
        int c=0;
        for(long i=1;i<=n;i++){
            long k=(i*(i+1))/2;
            if(k<=n){
                nums[c++]=k;
            }
            else break;
        }
        for(int i=0;i<c;i++){
            long t=n-nums[i];
            int ind=binarySearch(nums,t,c);
            if(-1!=ind){
                System.out.println("YES");
                return;
            }
        }
        System.out.println("NO");
        
      
    }
    public static int binarySearch(long[] search, long find, int r) {
        int start, end, midPt;
        start = 0;
        end = r - 1;
        while (start <= end) {
            midPt = (start + end) / 2;
            if (search[midPt] == find) {
                    return midPt;
            } else if (search[midPt] < find) {
                    start = midPt + 1;
            } else {
                    end = midPt - 1;
            }
        }
        return -1;
    }

    /****************************************************************/
    public static int[] toIntArray()throws Exception{
       String str[]=br.readLine().split(" ");
       int k[]=new int[str.length];
       for(int i=0;i<str.length;i++){
            k[i]=Integer.parseInt(str[i]);
       }
       return k;
    }
    public static int toInt()throws Exception{
       return Integer.parseInt(br.readLine());
    }
    public static long[] toLongArray()throws Exception{
       String str[]=br.readLine().split(" ");
       long k[]=new long[str.length];
       for(int i=0;i<str.length;i++){
            k[i]=Long.parseLong(str[i]);
       }
       return k;
    }
    public static long toLong()throws Exception{
       return Long.parseLong(br.readLine());
    }
    public static double[] toDoubleArray()throws Exception{
       String str[]=br.readLine().split(" ");
       double k[]=new double[str.length];
       for(int i=0;i<str.length;i++){
            k[i]=Double.parseDouble(str[i]);
       }
       return k;
    }
    public static double toDouble()throws Exception{
       return Double.parseDouble(br.readLine());
    }
    public static String toStr()throws Exception{
       return br.readLine();
    }
    public static String[] toStrArray()throws Exception{
       String str[]=br.readLine().split(" ");
       return str;
    }
    /****************************************************************/

}