You are playing a game of Jongmah. You don't need to know the rules to solve this problem. You have n tiles in your hand. Each tile has an integer between 1 and m written on it.

To win the game, you will need to form some number of triples. Each triple consists of three tiles, such that the numbers written on the tiles are either all the same or consecutive. For example, 7, 7, 7 is a valid triple, and so is 12, 13, 14, but 2,2,3 or 2,4,6 are not. You can only use the tiles in your hand to form triples. Each tile can be used in at most one triple.

To determine how close you are to the win, you want to know the maximum number of triples you can form from the tiles in your hand.

Input

The first line contains two integers integer n and m (1 ≤ n, m ≤ 10^6) — the number of tiles in your hand and the number of tiles types.

The second line contains integers a_1, a_2, …, a_n (1 ≤ a_i ≤ m), where a_i denotes the number written on the i-th tile.

Output

Print one integer: the maximum number of triples you can form.

Examples

Input

10 6
2 3 3 3 4 4 4 5 5 6


Output

3


Input

12 6
1 5 3 3 3 4 3 5 3 2 3 3


Output

3


Input

13 5
1 1 5 1 2 3 3 2 4 2 3 4 5


Output

4

Note

In the first example, we have tiles 2, 3, 3, 3, 4, 4, 4, 5, 5, 6. We can form three triples in the following way: 2, 3, 4; 3, 4, 5; 4, 5, 6. Since there are only 10 tiles, there is no way we could form 4 triples, so the answer is 3.

In the second example, we have tiles 1, 2, 3 (7 times), 4, 5 (2 times). We can form 3 triples as follows: 1, 2, 3; 3, 3, 3; 3, 4, 5. One can show that forming 4 triples is not possible.
import java.io.*;
import java.util.*;

public class Main {
    //static long mod=1000000007;
    public static void main(String[] args){
    	int n=ni(),m=ni();
    	int[] count=new int[m];
    	for(int i=0;i<n;i++) count[ni()-1]++;
    	int inf=Integer.MIN_VALUE/10;
    	if(m<3){
    		pl(count[0]/3+(m==2?count[1]/3:0));
    		flush();
    		return;
    	}
    	
    	int T=5;
    	int[][][] dp=new int[m][T][T-2];
    	for(int i=0;i<T;i++){
    		if(i>count[0]){
    			Arrays.fill(dp[0][i],inf);
    			continue;
    		}
    		for(int j=0;j<T-2;j++){
    			dp[0][i][j]=(count[0]-i)/3;
    			if(j>0) dp[0][i][j]=inf;
    		}
    	}
    	for(int i=0;i<T;i++){
    		for(int j=0;j<T-2;j++){
    			dp[1][i][j]=dp[0][j][0]+(count[1]-i)/3;
    			if(i>count[1] || j>count[0]) dp[1][i][j]=inf;
    		}
    	}
    	for(int i=2;i<m;i++){
    		for(int j=0;j<T;j++){
    			if(j>count[i]){
    				Arrays.fill(dp[i][j],inf);
    				continue;
    			}
    			for(int k=0;k<T-2;k++){
    				if(k>count[i-1]){
    					dp[i][j][k]=inf;
    					continue;
    				}
    				for(int t=0;t<T-2;t++){
    					dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][k][t]+(count[i]-j)/3);
    					for(int s=1;s<T;s++){
    						if(k+s<T && j<=count[i]-s){
    							for(int h=s;h<T-2;h++){
    								dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][k+s][h]+s+(count[i]-j-s)/3);
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	pl(dp[m-1][0][0]);
        flush();
    }
    
    
    
    
    
    
	private static final byte[] buffer = new byte[1024];
	private static int ptr = 0;
	private static int buflen = 0;
	private static boolean hasNextByte() {
		if (ptr < buflen)  return true;
		else{
			ptr = 0;
			try {
				buflen = System.in.read(buffer);
			} catch (IOException e) {e.printStackTrace();}
			if (buflen <= 0)  return false;
		}
		return true;
	}
	private static int readByte() { return hasNextByte() ? buffer[ptr++] : -1;}
	private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	private static void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	public static boolean hasNext() { skipUnprintable(); return hasNextByte();}
	public static String next() {
		if (!hasNext()) throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		for(int b = readByte();isPrintableChar(b);b = readByte()) {
			sb.appendCodePoint(b);
		}
		return sb.toString();
	}
	public static int nextInt() {return (int)nextLong();}
	public static long nextLong() {
		if (!hasNext()) throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b)  throw new NumberFormatException();
		while(true){
			if ('0' <= b && b <= '9') n = n * 10 + b-'0';
			else if(b == -1 || !isPrintableChar(b)) return minus ? -n : n;
			else throw new NumberFormatException();
			b = readByte();
		}
	}
	public static long[] nextLongArray(int i){
		long[] result=new long[i];
		for(int j=0;j<i;j++)  result[j]=nextLong();
		return result;
	}
	public static void nextLongArray(long[]... arrays){
		for(int j=0;j<arrays[0].length;j++)
			for(long[] array:arrays) array[j]=nextLong();
	}
	public static int[] nextIntArray(int i){
		int[] result=new int[i];
		for(int j=0;j<i;j++)  result[j]=nextInt();
		return result;
	}
	public static void nextIntArray(int[]... arrays){
		for(int j=0;j<arrays[0].length;j++)
			for(int[] array:arrays)  array[j]=nextInt();
	}
	public static int ni(){return nextInt();}
	public static long nl(){return nextLong();}
	public static int[] nia(int n){return nextIntArray(n);}
	public static long[] nla(int n){return nextLongArray(n);}
	public static String ne(){return next();}
	
	static StringBuilder sb=new StringBuilder();
	public static void flush(){
		System.out.print(sb);
		sb=new StringBuilder();
	}
	public static void pr(Object o){sb.append(o);}
	public static void pl(Object o){sb.append(o).append("\n");}
	public static void pl(){sb.append("\n");}
	public static int lastLowerIndex(long[] array,long lo){return lastLowerOrEqualIndex(array,lo-1);}
	public static int lastLowerOrEqualIndex(long[] array,long lo){
		int res=Arrays.binarySearch(array,lo);
		return res<0?-res-2:res;
	}
	public static long gcd(long a,long b){
		if(a>b)a%=b;
		while(a>0){
			b%=a;
			if(b==0)return a;
			a%=b;
		}
		return b;
	}
	public static long modPow(long a,long b,long mod){
		long c=1;
		while(b>0){
			if(b%2==1)  c=(c*a)%mod;
			a=(a*a)%mod;
			b/=2;
		}
		return c;
	}
	public static long inv(long a,long mod){
		long b=mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d=a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}
	static long time=0;
	public static void time(){
		if(time==0) time=System.nanoTime();
		else{
			long t=System.nanoTime();
			pl((t-time)/1000000000.0+"sec");
			time=t;
		}
	}
	public static Integer[] sortedIndex(long[] a){
            Integer[] res=new Integer[a.length];
            for(int i=0;i<a.length;i++)	res[i]=i;
            mergesortIndex(res,a,0,a.length);
            return res;
        }
        private static Integer[] stem=new Integer[200005];
        private static void mergesortIndex(Integer[] index,long[] a, int s, int e){
            if(e - s <= 1)return;
            int h = s+e>>1;
            mergesortIndex(index,a, s, h);
            mergesortIndex(index,a, h, e);
            int p = 0;
            int i= s, j = h;
            for(;i < h && j < e;)stem[p++] = a[(int)index[i]] < a[(int)index[j]] ? index[i++] : index[j++];
            while(i < h)stem[p++] = index[i++];
            while(j < e)stem[p++] = index[j++];
            System.arraycopy(stem, 0, index, s, e-s);
        }
        private static long[] stmp=new long[200005];
        private static void mergesort(long[] a, int s, int e){
            if(e - s <= 1)return;
            int h = s+e>>1;
            mergesort(a, s, h);
            mergesort(a, h, e);
            int p = 0;
            int i= s, j = h;
            for(;i < h && j < e;)stmp[p++] = a[i] < a[j] ? a[i++] : a[j++];
            while(i < h)stmp[p++] = a[i++];
            while(j < e)stmp[p++] = a[j++];
            System.arraycopy(stmp, 0, a, s, e-s);
        }
}