Problem: The Shuseki Islands are an archipelago of 30001 small islands in the Yutampo Sea. The islands are evenly spaced along a line, numbered from 0 to 30000 from the west to the east. These islands are known to contain many treasures. There are n gems in the Shuseki Islands in total, and the i-th gem is located on island pi.

Mr. Kitayuta has just arrived at island 0. With his great jumping ability, he will repeatedly perform jumps between islands to the east according to the following process: 

  * First, he will jump from island 0 to island d. 
  * After that, he will continue jumping according to the following rule. Let l be the length of the previous jump, that is, if his previous jump was from island prev to island cur, let l = cur - prev. He will perform a jump of length l - 1, l or l + 1 to the east. That is, he will jump to island (cur + l - 1), (cur + l) or (cur + l + 1) (if they exist). The length of a jump must be positive, that is, he cannot perform a jump of length 0 when l = 1. If there is no valid destination, he will stop jumping. 



Mr. Kitayuta will collect the gems on the islands visited during the process. Find the maximum number of gems that he can collect.

Input

The first line of the input contains two space-separated integers n and d (1 ≤ n, d ≤ 30000), denoting the number of the gems in the Shuseki Islands and the length of the Mr. Kitayuta's first jump, respectively.

The next n lines describe the location of the gems. The i-th of them (1 ≤ i ≤ n) contains a integer pi (d ≤ p1 ≤ p2 ≤ ... ≤ pn ≤ 30000), denoting the number of the island that contains the i-th gem.

Output

Print the maximum number of gems that Mr. Kitayuta can collect.

Examples

Input

4 10
10
21
27
27


Output

3


Input

8 8
9
19
28
36
45
55
66
78


Output

6


Input

13 7
8
8
9
16
17
17
18
21
23
24
24
26
30


Output

4

Note

In the first sample, the optimal route is 0  →  10 (+1 gem)  →  19  →  27 (+2 gems)  → ...

In the second sample, the optimal route is 0  →  8  →  15  →  21 →  28 (+1 gem)  →  36 (+1 gem)  →  45 (+1 gem)  →  55 (+1 gem)  →  66 (+1 gem)  →  78 (+1 gem)  → ...

In the third sample, the optimal route is 0  →  7  →  13  →  18 (+1 gem)  →  24 (+2 gems)  →  30 (+1 gem)  → ...

Solution (in JAVA):

Solution:
import java.util.*;		
import java.util.function.Function;
import java.util.stream.Collectors;
import java.io.*;
import java.math.*;
public class Main{
    static public void main(String args[])throws IOException{
        int tt=1;
        StringBuilder sb=new StringBuilder();
        for(int ttt=1;ttt<=tt;ttt++){
            int n=i();
            d=i();
            int[] p=new int[n];
            a=new int[30001];
            for(int i=0;i<n;i++){
                p[i]=i();
                a[p[i]]++;  
            }
            dp=new int[30001][1000];
            for(int i=0;i<30001;i++){
                Arrays.fill(dp[i],-1);
            }
            int max=0;
            max=Math.max(max,recur(d,d));
            sb.append(max+"\n");
        }
        System.out.print(sb.toString());
    }
    static int[] a;
    static int d;
    static int dp[][];
    static int recur(int index,int jump) {
        if(index>=30001 || index < 0) {
            return 0;
        }
        int jj = jump - (d-250);
        if(dp[index][jj] != -1) {
            return dp[index][jj];
        }
        int ans=0;
        if (jump > 0) {
            ans=Math.max(ans,a[index]+recur(index+jump,jump));
        }
        ans=Math.max(ans,a[index]+recur(index+jump+1,jump+1));
        if(jump-1>0) {
            ans=Math.max(ans,a[index]+recur(index+jump-1,jump-1));
        }
        dp[index][jj] = ans;
        return ans;
    }
    static class Pair{
        int x;
        int y;
        Pair(int x, int y){
            this.x=x;
            this.y=y;
        }
        @Override
        public int hashCode() 
        { 
                final int temp = 14; 
                int ans = 1; 
                ans =x*31+y*13; 
                return (int)ans;
        }
        @Override
         public boolean equals(Object o) 
         { 
             if (this == o) { 
                 return true; 
             } 
             if (o == null) { 
                 return false; 
             } 
             if (this.getClass() != o.getClass()) { 
                 return false; 
             } 
             Pair other = (Pair)o; 
             if (this.x != other.x || this.y!=other.y) { 
                 return false; 
             } 
             return true; 
         }
    } 
    static InputReader in=new InputReader(System.in);
    static OutputWriter out=new OutputWriter(System.out);
    static ArrayList<ArrayList<Integer>> graph;
    static int mod=1000000007;
  //  static class Pair{
  //      int x;
  //      int y;
  //      int z;
   //     Pair(int x,int y,int z){
             /*   this.x=x;
                this.y=y;
                this.z=z; */
    //    }
        /*@Override
        public int hashCode() 
        { 
                final int temp = 14; 
                int ans = 1; 
                ans =x*31+y*13; 
                return (int)ans;
        }
    @Override
     public boolean equals(Object o) 
     { 
         if (this == o) { 
             return true; 
         } 
         if (o == null) { 
             return false; 
         } 
         if (this.getClass() != o.getClass()) { 
             return false; 
         } 
         Pair other = (Pair)o; 
         if (this.x != other.x || this.y!=other.y) { 
             return false; 
         } 
         return true; 
     }*/
  //   }
    public static int[] sort(int[] a){
        int n=a.length;
        ArrayList<Integer> ar=new ArrayList<>();
        for(int i=0;i<a.length;i++){
                ar.add(a[i]);
        }
        Collections.sort(ar);
        for(int i=0;i<n;i++){
                a[i]=ar.get(i);
        }
        return a;
     }
    public static long pow(long a, long b){
        long result=1;
        while(b>0){
            if (b % 2 != 0){
                result=(result*a)%mod;
                b--;
            } 
            a=(a*a)%mod;
            b /= 2;
        }   
        return result;
    }
    public static long gcd(long a, long b){
        if (a == 0){
            return b;
        }
        return gcd(b%a, a);
    }
    public static long lcm(long a, long b){
        return a*(b/gcd(a,b));
    }
    public static long l(){
        String s=in.String();
        return Long.parseLong(s);
    }
    public static void pln(String value){
        System.out.println(value);
    }
    public static int i(){
        return in.Int();
    }
    public static String s(){
        return in.String();
    }
}
class InputReader 
{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;
    public InputReader(InputStream stream) {
       this.stream = stream;
    }
    public int read() {
        if (numChars== -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }
    public int Int() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
           sgn = -1;
           c = read();
        }
        int res = 0;
        do {
           if (c < '0' || c > '9')
               throw new InputMismatchException();
           res *= 10;
           res += c - '0';
           c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }
    public String String() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    } 
    public boolean isSpaceChar(int c) {
       if (filter != null)
           return filter.isSpaceChar(c);
       return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    } 
    public String next() {
       return String();
    } 
    public interface SpaceCharFilter {
       public boolean isSpaceChar(int ch);
    }
}
class OutputWriter {
    private final PrintWriter writer;
    public OutputWriter(OutputStream outputStream) {
       writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }
    public OutputWriter(Writer writer) {
       this.writer = new PrintWriter(writer);
    }
    public void print(Object...objects) {
       for (int i = 0; i < objects.length; i++) {
           if (i != 0)
               writer.print(' ');
           writer.print(objects[i]);
       }
    }
    public void printLine(Object...objects) {
       print(objects);
       writer.println();
    }
    public void close() {
       writer.close();
    }
    public void flush() {
       writer.flush();
    }
 }
class IOUtils {
    public static int[] readIntArray(InputReader in, int size) {
        int[] array = new int[size];
        for (int i = 0; i < size; i++)
                array[i] = in.Int();
        return array;
    }
}