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[][][] dp=new int[m+1][3][3];
    	for(int i=1;i<=m;i++){
    		for(int j=0;j<3;j++){
    			for(int k=0;k<3;k++){
    				for(int t=0;t<3;t++){
    					if((count[i-1]-j-k-t)>=0)
    						dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][k][t]+j+(count[i-1]-j-k-t)/3);
    				}
    			}
    		}
    	}
    	pl(dp[m][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);
        }
}


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];
    	for(int i=0;i<T;i++){
    		dp[0][i][0]=(count[0]-i)/3;
    		if(i>count[0]) dp[0][i][0]=inf;
    	}
    	for(int i=0;i<T;i++){
    		for(int j=0;j<T;j++){
    			dp[1][i][j]=dp[0][j][0]+(count[1]-i)/3;
    			if(i>count[1]) dp[1][i][j]=inf;
    		}
    	}
    	for(int i=2;i<m;i++){
    		for(int j=0;j<T;j++){
    			for(int k=0;k<T;k++){
    				for(int t=0;t<T;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;h++){
    								dp[i][j][k]=Math.max(dp[i][j][k],dp[i-1][k+s][h]+s+(count[i]-j-s)/3);
    							}
    						}
    					}
    					if(j>count[i]) dp[i][j][k]=inf;
    					if(k>count[i-1]) dp[i][j][k]=inf;
    				}
    			}
    		}
    	}
    	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);
        }
}


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++){
    		dp[0][i][0]=(count[0]-i)/3;
    		if(i>count[0]) dp[0][i][0]=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);
    				break;
    			}
    			for(int k=0;k<T-2;k++){
    				if(k>count[i-1]){
    					dp[i][j][k]=inf;
    					break;
    				}
    				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);
        }
}


import java.io.IOException;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Objects;

public class Main{
	static int[] a;
	static HashMap<Pair,Integer>[] dp;
	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		//System.out.println(a[3]);
		dp = new HashMap[m+1];
		for(int i=0;i<=m;i++){
			dp[i] = new HashMap<Pair,Integer>();
		}
		for(int i=0;i*3<=a[1];i++){
			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]*3-j<=8){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2].put(P,i+j);
				}
			}
			}
		}
		for(int i=2;i<m;i++){
			for(Pair p:dp[i].keySet()){
				//System.out.println(p.a + " " + p.b);
				int num = dp[i].get(p);
				for(int j=0;j*3<=a[i+1];j++){
					int forren = a[i+1] - 3*j;
					int min = (int) Math.min(Math.min(p.a,p.b),forren);
					if(min<3){
						for(int k=0;k<=min;k++){
							//System.out.println("jk is" + j + " " + k);
							Pair q = new Pair(p.b-k,(long)forren-k);
							if(q.a<=5&&q.b<=8){
							//System.out.println("Pair is" + q.a + " " + q.b);
							if(dp[i+1].containsKey(q)){
								dp[i+1].put(q,Math.max(dp[i+1].get(q),num + j + k));
							}else{
								dp[i+1].put(q,num + j + k);
							}
							}
						}
					}
				}
			}
		}
		int max = 0;
		for(Pair p:dp[m].keySet()){
			int d = dp[m].get(p);
			max = (int) Math.max(max, d);
		}
		//System.out.println(dp[4].get(new Pair(2,2)));
		System.out.println(max);

	}

}

class Pair{
	long a;
	long b;

	Pair(long p,long q){
		this.a = p;
		this.b = q;
	}

	public boolean equals(Object o){
		Pair O = (Pair) o;
		if(O.a==this.a&&O.b==this.b){
			return true;
		}else{
			return false;
		}

	}

	public int hashCode(){
		return Objects.hash(a,b);
	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Objects;

public class Main{
	static int[] a;
	static HashMap<Pair,Integer>[] dp;
	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}

		//System.out.println(a[3]);
		dp = new HashMap[m+1];
		for(int i=0;i<=m;i++){
			dp[i] = new HashMap<Pair,Integer>();
		}
		for(int i=0;i*3<=a[1];i++){
			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]*3-j<=8){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2].put(P,i+j);
				}
			}
			}
		}
		for(int i=2;i<m;i++){
			for(Pair p:dp[i].keySet()){
				//System.out.println(p.a + " " + p.b);
				int num = dp[i].get(p);
				for(int j=0;j*3<=a[i+1];j++){
					int forren = a[i+1] - 3*j;
					int min = (int) Math.min(Math.min(p.a,p.b),forren);
					if(min<3){
						for(int k=0;k<=min;k++){
							//System.out.println("jk is" + j + " " + k);
							Pair q = new Pair(p.b-k,(long)forren-k);
							if(q.a<=5&&q.b<=8){
							//System.out.println("Pair is" + q.a + " " + q.b);
							if(dp[i+1].containsKey(q)){
								dp[i+1].put(q,Math.max(dp[i+1].get(q),num + j + k));
							}else{
								dp[i+1].put(q,num + j + k);
							}
							}
						}
					}
				}
			}
		}
		int max = 0;
		for(Pair p:dp[m].keySet()){
			int d = dp[m].get(p);
			max = (int) Math.max(max, d+p.a/3+p.b/3);
		}
		//System.out.println(dp[4].get(new Pair(2,2)));
		System.out.println(max);

	}

}

class Pair{
	long a;
	long b;

	Pair(long p,long q){
		this.a = p;
		this.b = q;
	}

	public boolean equals(Object o){
		Pair O = (Pair) o;
		if(O.a==this.a&&O.b==this.b){
			return true;
		}else{
			return false;
		}

	}

	public int hashCode(){
		return Objects.hash(a,b);
	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Objects;

public class Main{
	static int[] a;
	static HashMap<Pair,Integer>[] dp;
	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		//System.out.println(a[3]);
		dp = new HashMap[3];
		for(int i=0;i<3;i++){
			dp[i] = new HashMap<Pair,Integer>();
		}

		for(int i=0;i*3<=a[1];i++){

			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]-3*j<=8){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2].put(P,i+j);

				}
			}
			}
		}
		for(int i=2;i<m;i++){
			for(Pair p:dp[i%3].keySet()){
				//System.out.println(p.a + " " + p.b);
				int num = dp[i%3].get(p);
				for(int j=0;j*3<=a[i+1];j++){
					int forren = a[i+1] - 3*j;
					int min = (int) Math.min(Math.min(p.a,p.b),forren);
					if(min<3){
						for(int k=0;k<=min;k++){
							//System.out.println("jk is" + j + " " + k);
							Pair q = new Pair(p.b-k,(long)forren-k);
							if(q.a<=5&&q.b<=8){
							//System.out.println("Pair is" + q.a + " " + q.b);
							if(dp[(i+1)%3].containsKey(q)){
								dp[(i+1)%3].put(q,Math.max(dp[(i+1)%3].get(q),num + j + k));
							}else{
								dp[(i+1)%3].put(q,num + j + k);
							}
							}
						}
					}
				}
			}
			dp[i%3].clear();
		}
		int max = 0;
		for(Pair p:dp[m%3].keySet()){
			int d = dp[m%3].get(p);
			max = (int) Math.max(max, d);
		}
		//System.out.println(dp[4].get(new Pair(2,2)));
		System.out.println(max);

	}

}

class Pair{
	long a;
	long b;

	Pair(long p,long q){
		this.a = p;
		this.b = q;
	}

	public boolean equals(Object o){
		Pair O = (Pair) o;
		if(O.a==this.a&&O.b==this.b){
			return true;
		}else{
			return false;
		}

	}

	public int hashCode(){
		return Objects.hash(a,b);
	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Objects;

public class Main{
	static int[] a;
	static HashMap<Pair,Integer>[] dp;
	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		//System.out.println(a[3]);
		dp = new HashMap[m+1];
		for(int i=0;i<=m;i++){
			dp[i] = new HashMap<Pair,Integer>();
		}

		for(int i=0;i*3<=a[1];i++){

			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]-3*j<=8){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2].put(P,i+j);

				}
			}
			}
		}
		for(int i=2;i<m;i++){
			for(Pair p:dp[i].keySet()){
				//System.out.println(p.a + " " + p.b);
				int num = dp[i].get(p);
				for(int j=0;j*3<=a[i+1];j++){
					int forren = a[i+1] - 3*j;
					int min = (int) Math.min(Math.min(p.a,p.b),forren);
					if(min<3){
						for(int k=0;k<=min;k++){
							//System.out.println("jk is" + j + " " + k);
							Pair q = new Pair(p.b-k,(long)forren-k);
							if(q.a<=5&&q.b<=8){
							//System.out.println("Pair is" + q.a + " " + q.b);
							if(dp[i+1].containsKey(q)){
								dp[i+1].put(q,Math.max(dp[i+1].get(q),num + j + k));
							}else{
								dp[i+1].put(q,num + j + k);
							}
							}
						}
					}
				}
			}
		}
		int max = 0;
		for(Pair p:dp[m].keySet()){
			int d = dp[m].get(p);
			max = (int) Math.max(max, d);
		}
		//System.out.println(dp[4].get(new Pair(2,2)));
		System.out.println(max);

	}

}

class Pair{
	long a;
	long b;

	Pair(long p,long q){
		this.a = p;
		this.b = q;
	}

	public boolean equals(Object o){
		Pair O = (Pair) o;
		if(O.a==this.a&&O.b==this.b){
			return true;
		}else{
			return false;
		}

	}

	public int hashCode(){
		return Objects.hash(a,b);
	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.NoSuchElementException;

public class Main{
	static int[] a;

	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}

		int[][][] dp = new int[m+1][5][7];
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		for(int i=0;i<=m;i++){
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					dp[i][j][k] = -1;
				}
			}
		}
		for(int i=0;i*3<=a[1];i++){

			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]-3*j<=7){
				dp[2][a[1]-3*i][a[2]-3*j] = i+j;

				}
			}
			}
		}
		for(int i=2;i<m;i++){
			int num = a[i+1];
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					if(dp[i][j][k]!=-1){
						for(int p=0;p*3<=num;p++){
							int forren = num - 3*p;
							int min = Math.min(Math.min(j,k),forren);
							if(min<3){
								for(int q=0;q<=min;q++){
									if(k-min<5&&forren-min<7){
										dp[i+1][k-min][forren-min] = Math.max(dp[i+1][k-min][forren-min], dp[i][j][k]+p+q);
									}
								}
							}
						}
					}
				}
			}
		}

		int max = 0;
		for(int j=0;j<5;j++){
			for(int k=0;k<7;k++){
				max = Math.max(max, dp[m][j][k]);
			}
		}
		System.out.println(max);

	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.HashMap;
import java.util.NoSuchElementException;
import java.util.Objects;

public class Main{
	static int[] a;
	static HashMap<Pair,Integer>[] dp;
	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}

		//System.out.println(a[3]);
		dp = new HashMap[m+1];
		for(int i=0;i<=m;i++){
			dp[i] = new HashMap<Pair,Integer>();
		}
		for(int i=0;i*3<=a[1];i++){
			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]*3-j<=8){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2].put(P,i+j);
				}
			}
			}
		}
		for(int i=2;i<m;i++){
			for(Pair p:dp[i].keySet()){
				//System.out.println(p.a + " " + p.b);
				int num = dp[i].get(p);
				for(int j=0;j*3<=a[i+1];j++){
					int forren = a[i+1] - 3*j;
					int min = (int) Math.min(Math.min(p.a,p.b),forren);
					if(min<3){
						for(int k=0;k<=min;k++){
							//System.out.println("jk is" + j + " " + k);
							Pair q = new Pair(p.b-k,(long)forren-k);
							if(q.a<=5&&q.b<=8){
							//System.out.println("Pair is" + q.a + " " + q.b);
							if(dp[i+1].containsKey(q)){
								dp[i+1].put(q,Math.max(dp[i+1].get(q),num + j + k));
							}else{
								dp[i+1].put(q,num + j + k);
							}
							}
						}
					}
				}
			}
		}
		int max = 0;
		for(Pair p:dp[m].keySet()){
			int d = dp[m].get(p);
			max = (int) Math.max(max, d);
		}
		//System.out.println(dp[4].get(new Pair(2,2)));
		System.out.println(max);

	}

}

class Pair{
	long a;
	long b;

	Pair(long p,long q){
		this.a = p;
		this.b = q;
	}

	public boolean equals(Object o){
		Pair O = (Pair) o;
		if(O.a==this.a&&O.b==this.b){
			return true;
		}else{
			return false;
		}

	}

	public int hashCode(){
		return Objects.hash(a,b);
	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.NoSuchElementException;

public class Main{
	static int[] a;

	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}

		int[][][] dp = new int[m+1][5][7];
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		for(int i=0;i<=m;i++){
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					dp[i][j][k] = -1;
				}
			}
		}
		for(int i=0;i*3<=a[1];i++){

			if(a[1]-3*i<5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]-3*j<7){
				dp[2][a[1]-3*i][a[2]-3*j] = i+j;

				}
			}
			}
		}
		for(int i=2;i<m;i++){
			int num = a[i+1];
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					if(dp[i][j][k]!=-1){
						for(int p=0;p*3<=num;p++){
							int forren = num - 3*p;
							int min = Math.min(Math.min(j,k),forren);
							if(min<3){
								for(int q=0;q<=min;q++){
									if(k-min<5&&forren-min<7){
										dp[i+1][k-min][forren-min] = Math.max(dp[i+1][k-min][forren-min], dp[i][j][k]+p+q);
									}
								}
							}
						}
					}
				}
			}
		}

		int max = 0;
		for(int j=0;j<5;j++){
			for(int k=0;k<7;k++){
				max = Math.max(max, dp[m][j][k]);
			}
		}
		System.out.println(max);

	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.io.IOException;
import java.util.NoSuchElementException;

public class Main{
	static int[] a;

	public static void main(String args[])throws Exception{

		FastScanner sc= new FastScanner();

		int n = sc.nextInt();
		int m = sc.nextInt();
		a = new int[m+1];
		for(int i=0;i<n;i++){
			a[sc.nextInt()]++;
		}

		int[][][] dp = new int[m+1][5][7];
		if(m==1){
			System.out.println(a[1]/3);
			return;
		}
		for(int i=0;i<=m;i++){
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					dp[i][j][k] = -1;
				}
			}
		}
		for(int i=0;i*3<=a[1];i++){

			if(a[1]-3*i<=5){
			for(int j=0;j*3<=a[2];j++){
				if(a[2]-3*j<=7){
				Pair P = new Pair(a[1]-3*i,a[2]-3*j);
				dp[2][a[1]-3*i][a[2]-3*j] = i+j;

				}
			}
			}
		}
		for(int i=2;i<m;i++){
			int num = a[i+1];
			for(int j=0;j<5;j++){
				for(int k=0;k<7;k++){
					if(dp[i][j][k]!=-1){
						for(int p=0;p*3<=num;p++){
							int forren = num - 3*p;
							int min = Math.min(Math.min(j,k),forren);
							if(min<3){
								for(int q=0;q<=min;q++){
									if(k-min<5&&forren-min<7){
										dp[i+1][k-min][forren-min] = Math.max(dp[i+1][k-min][forren-min], dp[i][j][k]+p+q);
									}
								}
							}
						}
					}
				}
			}
		}

		int max = 0;
		for(int j=0;j<5;j++){
			for(int k=0;k<7;k++){
				max = Math.max(max, dp[m][j][k]);
			}
		}
		System.out.println(max);

	}

}

class FastScanner {
    private final java.io.InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    private void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
    public boolean hasNext() { skipUnprintable(); return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public 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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        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 *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return (int) (minus ? -n : n);
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}


import java.util.*;

import java.io.*;
import java.math.BigInteger;

public class D {
	FastScanner in;
	PrintWriter out;
	boolean systemIO = true;

	public class Pair implements Comparable<Pair> {
		long x;
		long y;

		public Pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public int compareTo(Pair o) {
			if (x > o.x) {
				return 1;
			}
			if (x < o.x) {
				return -1;
			}
			if (y > o.y) {
				return 1;
			}
			if (y < o.y) {
				return -1;
			}
			return 0;
		}

	}

	public class Fenvik {
		int[] sum;

		public Fenvik(int n) {
			sum = new int[n];
		}

		public void add(int x, int d) {
			for (int i = x; i < sum.length; i = (i | (i + 1))) {
				sum[i] += d;
			}
		}

		public int sum(int r) {
			int ans = 0;
			for (int i = r; i >= 0; i = (i & (i + 1)) - 1) {
				ans += sum[i];
			}
			return ans;
		}

		public int sum(int l, int r) {
			if (l > r) {
				return 0;
			}
			return sum(r) - sum(l - 1);
		}
	}

	public long gcd(long x, long y) {
		if (y == 0) {
			return x;
		}
		if (x == 0) {
			return y;
		}
		return gcd(y, x % y);
	}

	public void solve() {
		int n = in.nextInt();
		int m = in.nextInt();
		int[] a = new int[m];
		for (int i = 0; i < n; i++) {
			a[in.nextInt() - 1]++;
		}
		int[][] dp = new int[6][6];
		boolean[][] can = new boolean[6][6];
		can[0][0] = true;
		for (int i = 0; i < a.length; i++) {
			int[][] dp1 = new int[6][6];
			boolean[][] can1 = new boolean[6][6];
			for (int j = 0; j < 6 && j <= a[i]; j++) {
				int d = (a[i] - j) / 3;
				for (int x = j; x < 6; x++) {
					for (int y = j; y < 6; y++) {
						if (can[x][y]) {
							can1[y - j][a[i] - 3 * d - j] = true;
							dp1[y - j][a[i] - 3 * d - j] = Math.max(dp1[y - j][a[i] - 3 * d - j], d + j + dp[x][y]);
							if (a[i] - 3 * d - j + 3 < 6 && d > 0) {
								can1[y - j][a[i] - 3 * d - j + 3] = true;
								dp1[y - j][a[i] - 3 * d - j + 3] = Math.max(dp1[y - j][a[i] - 3 * d - j + 3], d - 1 + j + dp[x][y]);
							}
						}
					}
				}
			}
			dp = dp1;
			can = can1;
//			for (int j = 0; j < can1.length; j++) {
//				for (int k = 0; k < can1.length; k++) {
//					System.out.print(can[j][k] + " ");
//				}
//				System.out.println();
//			}
//			System.out.println();
//			for (int j = 0; j < can1.length; j++) {
//				for (int k = 0; k < can1.length; k++) {
//					System.out.print(dp[j][k] + " ");
//				}
//				System.out.println();
//			}
//			System.out.println();
		}
		int ans = 0;
		for (int i = 0; i < can.length; i++) {
			for (int j = 0; j < can.length; j++) {
				if (can[i][j]) {
					ans = Math.max(ans, dp[i][j]);
				}
			}
		}
		System.out.println(ans);
	}

	public void run() {
		try {
			if (systemIO) {
				in = new FastScanner(System.in);
				out = new PrintWriter(System.out);
			} else {
				in = new FastScanner(new File("input.txt"));
				out = new PrintWriter(new File("output.txt"));
			}
			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String nextLine() {
			try {
				return br.readLine();
			} catch (IOException e) {
				return null;
			}
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

	}

	// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
	public static void main(String[] arg) {
		new D().run();
	}
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {

	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long M = 1000000007;

	public int solve(int[] tiles, int m) {
		int cnt[] = new int[m + 2];
		for (int i : tiles)
			cnt[i]++;
		int[][][] dp = new int[m + 2][3][3]; // dp[i][t1][t2]
		// i-2, i-1, i
		// i-1, i, i+1
		// i, i+1, i+2
		// 2 3 3 3 4 4 4 5 5 6
		// dp[0][0] = 0
		// dp[0][1] = 1
		// dp[0][2] = 0

		for (int i = 1; i <= m + 1; i++) {
			for (int l = 0; l < 3; l++)
				for (int k = 0; k < 3; k++) {
					for (int j = 0; j < 3; j++) {
						if (cnt[i] < j + k + l)
							break;
						dp[i][k][l] = Math.max(dp[i][k][l], dp[i - 1][j][k] + l + (cnt[i] - j - k - l) / 3);
					}
//					tr(i, k, l, f[i][k][l]);
				}
		}

		return dp[m][0][0];
	}

	void solve() {
		int n = ni();
		int m = ni();
		int[] a = na(n);
		out.println(solve(a, m));
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		work();
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	void work() {
		int n=ni(),m=ni();
		int[] count=new int[m+1];
		for(int i=0;i<n;i++) {
			count[ni()]++;
		}
		int[][] dp=new int[3][3];
		for(int p=0;p<m;p++) {
			int[][] ndp=new int[3][3];
			for(int i=0;i<3;i++) {
				for(int j=0;j<3;j++) {
					for(int k=0;k<3;k++) {//ndp[j][k],dp[i][j]
						int r=count[p+1]-i-j-k;
						if(r<0)continue;
						ndp[j][k]=Math.max(dp[i][j]+k+r/3, ndp[j][k]);
					}
				}
			}
			dp=ndp;
		}
		out.println(dp[0][0]);
	}

	//input
	@SuppressWarnings("unused")
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}

	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}

	public String next()
	{
		while(st==null || !st.hasMoreElements())//回车，空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt()
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class D {

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int[] count = new int[m];
		for (int i = 0; i < n; i++) {
			count[sc.nextInt() - 1]++;
		}
		int[][][] table = new int[m][5][3];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < 5; j++) {
				for (int k = 0; k < 3; k++) {
					table[i][j][k] = -n;
				}
			}
		}
		int max;
		for (int i = m - 1; i >= 0 ; i--) {
			for (int j = 0; j < 5; j++) if (j <= count[i]) {
				for (int k = 0; k < 3; k++) if (i + 1 < m && k <= count[i+1] || k == 0) {
					table[i][j][k] = 0;
					int rem = count[i] - j;
					max = Math.min(rem, (i + 1 < m ? count[i+1] : 0) - k);
					max = Math.min(max, 2);
					for (int l = 0; l <= max; l++) {
						table[i][j][k] = Math.max(table[i][j][k], (i+1 < m ? table[i+1][k+l][l] : 0) + l + (rem-l)/3);
					}
				}
			}
		}
		out.println(table[0][0][0]);

		out.flush();
	}

	static class MyScanner {
		private BufferedReader br;
		private StringTokenizer tokenizer;

		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}
	}
}


import java.util.*;

public class jong {
    public static void main( String[] args ) {
	Scanner in = new Scanner( System.in );
	int n = in.nextInt(), m = in.nextInt();
	int[] a = new int[m + 3];
	for ( int i = 0; i < n; i++ )
	    a[in.nextInt()]++;
	int[][][] dp = new int[m + 1][3][3];
	for ( int i = 1; i <= m; i++ )
	    for ( int j = 0; j < 3; j++ )
		for ( int k = 0; k < 3; k++ )
		    for ( int l = 0; l < 3; l++ ) {
			int r = a[i] - j - k - l;
			int r1 = a[i + 1] - k - l;
			int r2 = a[i + 2] - l;
			if ( r >= 0 && r1 >= 0 && r2 >= 0 )
			    dp[i][k][l] = Math.max( dp[i][k][l], dp[i - 1][j][k] + l + (r / 3) );
		    }
	int mx = -1;
	for ( int i = 0; i < 3; i++ )
	    for ( int j = 0; j < 3; j++ )
		mx = Math.max( mx, dp[m][i][j] );
	System.out.println( mx );
    }
}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        for(int i=1;i<=n;i++) f[ni()]++;
        int ans=0;
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                f[i]=6+f[i]%3;
            }

        }
        dp=new int[m+1][9][9];
        for(int i=1;i<=m;i++) for(int j=0;j<=8;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(1,0,0);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) return 0;

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];
      //  pw.println(i);
        int mx=0;
        int kk=Math.min(2,Math.min(c1,Math.min(c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(c1-k)/3;
           mx=Math.max(mx,d+go(i+1,c2-k,f[i]-k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if (!INPUT.isEmpty()) tr(System.currentTimeMillis() - s + "ms");

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        for(int i=1;i<=n;i++) f[ni()]++;
        int ans=0;
        if(m<=2){

            for(int i=1;i<=m;i++) ans+=f[i]/3;
            pw.println(ans);
            return;
        }
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                f[i]=6+f[i]%3;
            }

        }
        dp=new int[m+1][3][3];
        for(int i=1;i<=m;i++) for(int j=0;j<=2;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(3,0,0);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) {

            return (f[i-2]-c1-c2)/3+(f[i-1]-c2)/3;
        }

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];
        //  pw.println(i);
        int mx=0;
        int kk=Math.min(2,Math.min(f[i-2]-c1-c2,Math.min(f[i-1]-c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(f[i-2]-c1-c2-k)/3;
            mx=Math.max(mx,d+go(i+1,c2,k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);

        Thread t = new Thread(null, null, "~", Runtime.getRuntime().maxMemory()){
            @Override
            public void run() {
                long s = System.currentTimeMillis();
                solve();

                pw.flush();
                if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
            }
        };
        t.start();
        t.join();

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        for(int i=1;i<=n;i++) f[ni()]++;
        int ans=0;
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                f[i]=6+f[i]%3;
            }

        }
        dp=new int[m+1][9][9];
        for(int i=1;i<=m;i++) for(int j=0;j<=8;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(1,0,0);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) {

            return c1/3+c2/3;
        }

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];
      //  pw.println(i);
        int mx=0;
        int kk=Math.min(2,Math.min(c1,Math.min(c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(c1-k)/3;
           mx=Math.max(mx,d+go(i+1,c2-k,f[i]-k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if (!INPUT.isEmpty()) tr(System.currentTimeMillis() - s + "ms");

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        extra=new int[m+1];

        for(int i=1;i<=n;i++) f[ni()]++;
        if(m<=2){
            int ans=0;
            for(int i=1;i<=m;i++) ans+=f[i]/3;
            pw.println(ans);
            return;
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                f[i]=6;
                extra[i]=f[i]%3;
            }

        }
        dp=new int[m+1][7][7];
        for(int i=1;i<=m;i++) for(int j=0;j<=6;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(3,f[1],f[2]);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int extra[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) {

            return (c1+extra[i-2])/3+(c2+extra[i-1])/3;
        }

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];
      //  pw.println(i);
        int mx=0;
        int kk=Math.min(2,Math.min(c1,Math.min(c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(c1+extra[i-2]-k)/3;
           mx=Math.max(mx,d+go(i+1,c2-k,f[i]-k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if (!INPUT.isEmpty()) tr(System.currentTimeMillis() - s + "ms");

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        extra=new int[m+1];

        for(int i=1;i<=n;i++) f[ni()]++;
        if(m<=2){
            int ans=0;
            for(int i=1;i<=m;i++) ans+=f[i]/3;
            pw.println(ans);
            return;
        }
        int ans=0;
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                extra[i]=f[i]%3;
                f[i]=6;

            }

        }
        dp=new int[m+1][7][7];
        for(int i=1;i<=m;i++) for(int j=0;j<=6;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(3,f[1],f[2]);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int extra[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) {

            return (c1+extra[i-2])/3+(c2+extra[i-1])/3;
        }

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];

        int mx=0;
        int kk=Math.min(2,Math.min(c1,Math.min(c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(c1+extra[i-2]-k)/3;
           mx=Math.max(mx,d+go(i+1,c2-k,f[i]-k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if (!INPUT.isEmpty()) tr(System.currentTimeMillis() - s + "ms");

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

    void solve() {
        n=ni(); m=ni();
        f=new int[m+1];
        for(int i=1;i<=n;i++) f[ni()]++;
        int ans=0;
        for(int i=1;i<=m;i++){
            if(f[i]>6){
                ans+=(f[i]-6)/3;
                f[i]=6+f[i]%3;
            }

        }
        dp=new int[m+1][3][3];
        for(int i=1;i<=m;i++) for(int j=0;j<=2;j++) Arrays.fill(dp[i][j],-1);
        ans+=go(3,0,0);
        pw.println(ans);
    }
    int n,m;
    int f[];
    int dp[][][];
    int go(int i,int c1,int c2){

        if(i>m) {

            return (f[i-2]-c1-c2)/3+(f[i-1]-c2)/3;
        }

        if(dp[i][c1][c2]!=-1) return dp[i][c1][c2];
        //  pw.println(i);
        int mx=0;
        int kk=Math.min(2,Math.min(f[i-2]-c1-c2,Math.min(f[i-1]-c2,f[i])));
        for(int k=0;k<=kk;k++){
            int d=k+(f[i-2]-c1-c2-k)/3;
            mx=Math.max(mx,d+go(i+1,c2,k));
        }
        dp[i][c1][c2]=mx;
        return mx;
    }
    long add(long a,long b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }
    long sub(long a,long b){
        a-=b;
        if(a<0) a+=M;
        return a;
    }
    long mul(long a,long b){
        a*=b;
        if(a>=M) a%=M;
        return a;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M = (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";

    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if (!INPUT.isEmpty()) tr(System.currentTimeMillis() - s + "ms");

    }

    public static void main(String[] args) throws Exception {
        new Main().run();
    }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if (lenbuf == -1) throw new InputMismatchException();
        if (ptrbuf >= lenbuf) {
            ptrbuf = 0;
            try {
                lenbuf = is.read(inbuf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (lenbuf <= 0) return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

    private double nd() {
        return Double.parseDouble(ns());
    }

    private char nc() {
        return (char) skip();
    }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while (p < n && !(isSpaceChar(b))) {
            buf[p++] = (char) b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for (int i = 0; i < n; i++) map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
        if (b == '-') {
            minus = true;
            b = readByte();
        }

        while (true) {
            if (b >= '0' && b <= '9') {
                num = num * 10 + (b - '0');
            } else {
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (INPUT.length() > 0) System.out.println(Arrays.deepToString(o));
    }

}