import java.util.*;
import java.io.*;
import static java.lang.Math.*;

/* spar5h */

public class cf4 implements Runnable {

	public void run() {

		InputReader s = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);

		int t = 1;

		while(t-- > 0) {

			int n = s.nextInt(), m = s.nextInt();

			int[] f = new int[m];

			for(int i = 0; i < n; i++)
				f[s.nextInt() - 1]++;

			if(m == 1) {
				w.println(f[0] / 3);
				continue;
			}

			long[][][] dp = new long[5][5][m];

			for(int j = 0; j < 5; j++) {
				for(int k = 0; k < 5; k++) {

					if(f[0] >= j && f[1] >= k)
						dp[j][k][1] = (f[0] - j) / 3 + (f[1] - k) / 3;
					else
						dp[j][k][1] = -1;
				}
			}

			for(int i = 2; i < m; i++) {
				for(int j = 0; j < 5; j++) {
					for(int k = 0; k < 5; k++) {

						dp[j][k][i] = -1;

						if(f[i] >= k && dp[0][j][i - 1] != -1) {
							dp[j][k][i] = max((f[i] - k) / 3 + dp[0][j][i - 1], dp[j][k][i]);
						}

						if(j + 1 < 5 && f[i] >= k + 1 && dp[1][j + 1][i - 1] != -1) {
							dp[j][k][i] = max((f[i] - k - 1) / 3 + dp[1][j + 1][i - 1] + 1, dp[j][k][i]);
						}

						if(j + 2 < 5 && f[i] >= k + 2 && dp[2][j + 2][i - 1] != -1) {
							dp[j][k][i] = max((f[i] - k - 2) / 3 + dp[2][j + 2][i - 1] + 2, dp[j][k][i]);
						}

					}
				}
			}

			long res = 0;

			for(int j = 0; j < 5; j++)
				for(int k = 0; k < 5; k++)
					res = max(dp[j][k][m - 1], res);

			w.println(res);
		}

		w.close();
	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {

			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars) {

				curChar = 0;

				try {
					numChars = stream.read(buf);
				}
				catch (IOException e) {
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}

			return buf[curChar++];
		}

		public String nextLine() {

			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			String str = "";

			try {
	            str = br.readLine();
	        }
	        catch (IOException e) {
	            e.printStackTrace();
	        }

	        return str;
		}

		public int nextInt() {

			int c = read();

			while(isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			int res = 0;

			do {
				if(c<'0'||c>'9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));

			return res * sgn;
		}

		public long nextLong() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			long res = 0;

			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}

			while (!isSpaceChar(c));
				return res * sgn;
		}

		public double nextDouble() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-') {
				sgn = -1;
				c = read();
			}

			double res = 0;

			while (!isSpaceChar(c) && c != '.') {

				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());

				if (c < '0' || c > '9')
					throw new InputMismatchException();

				res *= 10;
				res += c - '0';
				c = read();
			}

			if (c == '.') {

				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}

			return res * sgn;
		}

		public String readString() {

			int c = read();

			while (isSpaceChar(c))
				c = read();

			StringBuilder res = new StringBuilder();

			do {
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));

			return res.toString();
		}

		public boolean isSpaceChar(int c) {

			if (filter != null)
				return filter.isSpaceChar(c);

			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public String next() {
			return readString();
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}

	}

	public static void main(String args[]) throws Exception {
		new Thread(null, new cf4(),"cf4",1<<26).start();
	}
}


import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;

public class Task {

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

        new Task().go();
    }

    PrintWriter out;
    Reader in;
    BufferedReader br;

    Task() throws IOException {

        try {

            //br = new BufferedReader( new FileReader("input.txt") );
            in = new Reader("input.txt");
            out = new PrintWriter( new BufferedWriter(new FileWriter("output.txt")) );
        }
        catch (Exception e) {

            //br = new BufferedReader( new InputStreamReader( System.in ) );
            in = new Reader();
            out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(System.out)) );
        }
    }

    void go() throws IOException {

        int t = 1;
        while (t > 0) {
            solve();
            //out.println();
            t--;
        }

        out.flush();
        out.close();
    }

    int inf = 2000000000;
    int mod = 1000000007;
    double eps = 0.000000001;

    int n;
    int m;

    ArrayList<Integer>[] g;
    int[] a;

    void solve() throws IOException {

        int n = in.nextInt();
        int m = in.nextInt();

        int[] cnt = new int[m+1];
        for (int i = 0; i < n; i++)
            cnt[in.nextInt()]++;

        ArrayList<Integer> list = new ArrayList<>();

        int[][][] dp = new int[m+1][3][3];

        for (int i = 0; i < m; i++) {

//            for (int t1 = 0; t1 < 3; t1++)
//                for (int t2 = 0; t2 < 3; t2++)
//                    dp[i+1][t1][t2] = dp[i][t1][t2];

            for (int t1 = 0; t1 < 3; t1++)
                for (int t2 = 0; t2 < 3; t2++)
                    for (int t3 = 0; t3 < 3; t3++) {
                        if (t1 + t2 + t3 <= cnt[i + 1]) {
                            int s = (cnt[i + 1] - t1 - t2 - t3) / 3 + t3;
                            dp[i + 1][t2][t3] = Math.max(dp[i + 1][t2][t3], dp[i][t1][t2] + s);
                        }
                    }
        }

        long ans = 0;

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                ans = Math.max(ans, dp[m][i][j]);

        out.print(ans);
    }

    int gcd(int a, int b){
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }

    class Pair implements Comparable<Pair>{
        int a;
        int b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int compareTo(Pair p) {
            if (a > p.a) return 1;
            if (a < p.a) return -1;
            if (b > p.b) return 1;
            if (b < p.b) return -1;
            return 0;
        }
    }

    class Item {

        int a;
        int b;
        int c;

        Item(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }

    }

    class Reader {

        BufferedReader  br;
        StringTokenizer tok;

        Reader(String file) throws IOException {
            br = new BufferedReader( new FileReader(file) );
        }

        Reader() throws IOException {
            br = new BufferedReader( new InputStreamReader(System.in) );
        }

        String next() throws IOException {

            while (tok == null || !tok.hasMoreElements())
                tok = new StringTokenizer(br.readLine());
            return tok.nextToken();
        }

        int nextInt() throws NumberFormatException, IOException {
            return Integer.valueOf(next());
        }

        long nextLong() throws NumberFormatException, IOException {
            return Long.valueOf(next());
        }

        double nextDouble() throws NumberFormatException, IOException {
            return Double.valueOf(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

    }

}


import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;

public class Task {

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

        new Task().go();
    }

    PrintWriter out;
    Reader in;
    BufferedReader br;

    Task() throws IOException {

        try {

            //br = new BufferedReader( new FileReader("input.txt") );
            in = new Reader("input.txt");
            out = new PrintWriter( new BufferedWriter(new FileWriter("output.txt")) );
        }
        catch (Exception e) {

            //br = new BufferedReader( new InputStreamReader( System.in ) );
            in = new Reader();
            out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(System.out)) );
        }
    }

    void go() throws IOException {

        int t = 1;
        while (t > 0) {
            solve();
            //out.println();
            t--;
        }

        out.flush();
        out.close();
    }

    int inf = 2000000000;
    int mod = 1000000007;
    double eps = 0.000000001;

    int n;
    int m;

    ArrayList<Integer>[] g;
    int[] a;

    void solve() throws IOException {

        int n = in.nextInt();
        int m = in.nextInt();

        int[] cnt = new int[m+2];
        for (int i = 0; i < n; i++)
            cnt[in.nextInt()]++;

        ArrayList<Integer> list = new ArrayList<>();

        int[][][] dp = new int[m+2][3][3];

        for (int i = 0; i <= m; i++) {

//            for (int t1 = 0; t1 < 3; t1++)
//                for (int t2 = 0; t2 < 3; t2++)
//                    dp[i+1][t1][t2] = dp[i][t1][t2];

            for (int t1 = 0; t1 < 3; t1++)
                for (int t2 = 0; t2 < 3; t2++)
                    for (int t3 = 0; t3 < 3; t3++) {
                        if (t1 + t2 + t3 <= cnt[i + 1]) {
                            int s = (cnt[i + 1] - t1 - t2 - t3) / 3 + t3;
                            dp[i + 1][t2][t3] = Math.max(dp[i + 1][t2][t3], dp[i][t1][t2] + s);
                        }
                    }
        }

        long ans = 0;

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                ans = Math.max(ans, dp[m+1][i][j]);

        out.print(ans);
    }

    int gcd(int a, int b){
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }

    class Pair implements Comparable<Pair>{
        int a;
        int b;

        Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }

        public int compareTo(Pair p) {
            if (a > p.a) return 1;
            if (a < p.a) return -1;
            if (b > p.b) return 1;
            if (b < p.b) return -1;
            return 0;
        }
    }

    class Item {

        int a;
        int b;
        int c;

        Item(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }

    }

    class Reader {

        BufferedReader  br;
        StringTokenizer tok;

        Reader(String file) throws IOException {
            br = new BufferedReader( new FileReader(file) );
        }

        Reader() throws IOException {
            br = new BufferedReader( new InputStreamReader(System.in) );
        }

        String next() throws IOException {

            while (tok == null || !tok.hasMoreElements())
                tok = new StringTokenizer(br.readLine());
            return tok.nextToken();
        }

        int nextInt() throws NumberFormatException, IOException {
            return Integer.valueOf(next());
        }

        long nextLong() throws NumberFormatException, IOException {
            return Long.valueOf(next());
        }

        double nextDouble() throws NumberFormatException, IOException {
            return Double.valueOf(next());
        }

        String nextLine() throws IOException {
            return br.readLine();
        }

    }

}


import java.util.*;
public class Main {
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		int m=in.nextInt();
		m+=2;
		int[] cnt=new int[m+1];
		for (int i=0;i<n;++i) {
			int x=in.nextInt();
			++cnt[x];
		}
		int[][][] dp=new int[m+1][3][3];
		for (int i=0;i<=m;++i) for (int j=0;j<3;++j) for (int k=0;k<3;++k) dp[i][j][k]=Integer.MIN_VALUE;
		dp[0][0][0]=0;
		for (int i=1;i<=m;++i)
			for (int a=0;a<3;++a)
				for (int b=0;b<3;++b)
					for (int c=0;c<3;++c) {
						if (a+b+c>cnt[i]) continue;
						dp[i][c][b]=Math.max(dp[i][c][b],dp[i-1][b][a]+c+(cnt[i]-a-b-c)/3);
					}
		int res=0;
		for (int a=0;a<3;++a)
			for (int b=0;b<3;++b)
				res=Math.max(res,dp[m][a][b]);
		System.out.println(res);
	}
}


//package sept;

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

public class TimePass implements Runnable {
    InputStream is;
    PrintWriter out;
    String INPUT = "10 6\r\n" +
    		"2 3 3 3 4 4 4 5 5 6";
    //boolean debug=false;
    boolean debug=true;
    static long mod=998244353;
    static long mod2=1000000007;

    void solve() throws IOException
	{
    	/*
    	int n=ni(),x=ni();
    	int[] a=na(n);
    	int[] from=new int[2*(n-1)];
    	int[] to=new int[2*(n-1)];
    	int ind=0;
    	for(int i=0;i<n-1;i++)
    	{
    		int u=ni()-1,v=ni()-1;
    		from[ind++]=u;
    		to[ind-1]=v;
    		from[ind++]=v;
    		to[ind-1]=u;
    	}
    	int[][] g=packD(n,from,to);
    	xor=new int[n];
    	int[] vis=new int[n];
    	dfs(0,a,g,vis);
    	if(xor[0]!=0 && xor[0]!=x)
    	{
    		out.println(0);
    		return;
    	}
    	*/
    	/*
    	int q=ni();
    	int[] a=na(q);
    	for(int i=0;i<q;i++)
    	{
    		for(int j=1;j<=Math.sqrt(a[i]);j++)
    		{
    			if(a[i]%j==0)
    			{

    				if(a[i]%(a[i]/j)==0 && j!=a[i]/j)
    				{

    				}
    			}
    		}
    	}
    	*/
    	int n=ni(),m=ni();
    	int[] a=na(n);
    	//Arrays.sort(a);
    	int[] cnt=new int[1000011];
    	for(int i=0;i<n;i++)
    	{
    		cnt[a[i]]++;
    	}
    	int[][][] dp=new int[2][3][3];
    	int ans=0;
    	for(int i=1;i<=1000000;i++)
    	{
    		for(int j=0;j<3;j++)
    		{
    			for(int k=0;k<3;k++)
    			{
    				for(int l=0;l<3;l++)
    				{
    					if(j+k+l<=cnt[i])
    					{
    						dp[1][k][l]=Math.max(dp[0][k][l], dp[0][j][k]+l+(cnt[i]-j-k-l)/3);
    					}
    				}
    			}
    		}
    		for(int j=0;j<3;j++)
    		{
    			for(int k=0;k<3;k++)
    			{
    				ans=Math.max(ans, dp[1][j][k]);
    				dp[0][j][k]=dp[1][j][k];
    			}
    		}
    	}
    	out.println(ans);
	}

    static int[] xor;

    static void dfs(int u,int[] a,int[][] g,int[] vis)
    {
    	xor[u]=a[u];

    	vis[u]=1;
    	for(int v:g[u])
    	{
    		if(vis[v]==0)
    		{
    			dfs(v,a,g,vis);
    			xor[u]=xor[u]^xor[v];
    		}
    	}
    }

	static int[][] packD(int n,int[] from,int[] to)
	{
		int[][] g=new int[n][];
		int[] p=new int[n];
		for(int f:from)
		{
			p[f]++;
		}
		int m=from.length;
		for(int i=0;i<n;i++)
		{
			g[i]=new int[p[i]];
		}
		for(int i=0;i<m;i++)
		{
			g[from[i]][--p[from[i]]]=to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
            //this.ind=ind;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    public void run()
    {
        if(debug)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        try {
			solve();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Thread(null,new TimePass(),"Main",1<<26).start();}

    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(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package sept;

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

public class TimePass implements Runnable {
    InputStream is;
    PrintWriter out;
    String INPUT = "10 6\r\n" +
    		"2 3 3 3 4 4 4 5 5 6";
    //boolean debug=false;
    boolean debug=true;
    static long mod=998244353;
    static long mod2=1000000007;

    void solve() throws IOException
	{
    	/*
    	int n=ni(),x=ni();
    	int[] a=na(n);
    	int[] from=new int[2*(n-1)];
    	int[] to=new int[2*(n-1)];
    	int ind=0;
    	for(int i=0;i<n-1;i++)
    	{
    		int u=ni()-1,v=ni()-1;
    		from[ind++]=u;
    		to[ind-1]=v;
    		from[ind++]=v;
    		to[ind-1]=u;
    	}
    	int[][] g=packD(n,from,to);
    	xor=new int[n];
    	int[] vis=new int[n];
    	dfs(0,a,g,vis);
    	if(xor[0]!=0 && xor[0]!=x)
    	{
    		out.println(0);
    		return;
    	}
    	*/
    	/*
    	int q=ni();
    	int[] a=na(q);
    	for(int i=0;i<q;i++)
    	{
    		for(int j=1;j<=Math.sqrt(a[i]);j++)
    		{
    			if(a[i]%j==0)
    			{

    				if(a[i]%(a[i]/j)==0 && j!=a[i]/j)
    				{

    				}
    			}
    		}
    	}
    	*/
    	int n=ni(),m=ni();
    	int[] a=na(n);
    	//Arrays.sort(a);
    	int[] cnt=new int[1000011];
    	for(int i=0;i<n;i++)
    	{
    		cnt[a[i]]++;
    	}
    	int[][][] dp=new int[2][3][3];
    	int ans=0;
    	for(int i=0;i<=1000000;i++)
    	{
    		for(int j=0;j<3;j++)
    		{
    			for(int k=0;k<3;k++)
    			{
    				for(int l=0;l<3;l++)
    				{
    					if(j+k+l<=cnt[i])
    					{
    						dp[1][k][l]=Math.max(dp[1][k][l], dp[0][j][k]+l+(cnt[i]-j-k-l)/3);
    					}
    				}
    			}
    		}
    		for(int j=0;j<3;j++)
    		{
    			for(int k=0;k<3;k++)
    			{
    				//ans=Math.max(ans, dp[1][j][k]);
    				int tmp=dp[0][j][k];
    				dp[0][j][k]=dp[1][j][k];
    				dp[1][j][k]=tmp;
    			}
    		}
    	}
    	out.println(dp[0][0][0]);
	}

    static int[] xor;

    static void dfs(int u,int[] a,int[][] g,int[] vis)
    {
    	xor[u]=a[u];

    	vis[u]=1;
    	for(int v:g[u])
    	{
    		if(vis[v]==0)
    		{
    			dfs(v,a,g,vis);
    			xor[u]=xor[u]^xor[v];
    		}
    	}
    }

	static int[][] packD(int n,int[] from,int[] to)
	{
		int[][] g=new int[n][];
		int[] p=new int[n];
		for(int f:from)
		{
			p[f]++;
		}
		int m=from.length;
		for(int i=0;i<n;i++)
		{
			g[i]=new int[p[i]];
		}
		for(int i=0;i<m;i++)
		{
			g[from[i]][--p[from[i]]]=to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
            //this.ind=ind;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    public void run()
    {
        if(debug)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        try {
			solve();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Thread(null,new TimePass(),"Main",1<<26).start();}

    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(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package sept;

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

public class TimePass implements Runnable {
    InputStream is;
    PrintWriter out;
    String INPUT = "10 6\r\n" +
    		"2 3 3 3 4 4 4 5 5 6";
    //boolean debug=false;
    boolean debug=true;
    static long mod=998244353;
    static long mod2=1000000007;

    void solve() throws IOException
	{
    	/*
    	int n=ni(),x=ni();
    	int[] a=na(n);
    	int[] from=new int[2*(n-1)];
    	int[] to=new int[2*(n-1)];
    	int ind=0;
    	for(int i=0;i<n-1;i++)
    	{
    		int u=ni()-1,v=ni()-1;
    		from[ind++]=u;
    		to[ind-1]=v;
    		from[ind++]=v;
    		to[ind-1]=u;
    	}
    	int[][] g=packD(n,from,to);
    	xor=new int[n];
    	int[] vis=new int[n];
    	dfs(0,a,g,vis);
    	if(xor[0]!=0 && xor[0]!=x)
    	{
    		out.println(0);
    		return;
    	}
    	*/
    	/*
    	int q=ni();
    	int[] a=na(q);
    	for(int i=0;i<q;i++)
    	{
    		for(int j=1;j<=Math.sqrt(a[i]);j++)
    		{
    			if(a[i]%j==0)
    			{

    				if(a[i]%(a[i]/j)==0 && j!=a[i]/j)
    				{

    				}
    			}
    		}
    	}
    	*/
    	int n=ni(),m=ni();
    	int[] a=na(n);
    	//Arrays.sort(a);
    	int[] cnt=new int[1000011];
    	for(int i=0;i<n;i++)
    	{
    		cnt[a[i]]++;
    	}
    	int[][][] dp=new int[2][3][3];
    	int ans=0;
    	for(int i=0;i<=1000006;i++)
    	{
    		for(int j=0;j<3;j++)
    		{
    			for(int k=0;k<3;k++)
    			{
    			    int p=cnt[i]-j-k;
				    int q=cnt[i+1]-k;
				    int r=cnt[i+2];
    				for(int l=0;l<3;l++)
    				{
    				    if(p<l || q<l || r<l)continue;
    					dp[1][k][l]=Math.max(dp[1][k][l], dp[0][j][k]+l+(cnt[i]-j-k-l)/3);
    				}
    			}
    		}
    		for(int j=0;j<3;j++)
    		{
    		    for(int k=0;k<3;k++)
    		    {
    		        ans=Math.max(ans,dp[1][j][k]);
    		        dp[0][j][k]=dp[1][j][k];
    		    }
    		}

    	}
    	out.println(ans);
	}

    static int[] xor;

    static void dfs(int u,int[] a,int[][] g,int[] vis)
    {
    	xor[u]=a[u];

    	vis[u]=1;
    	for(int v:g[u])
    	{
    		if(vis[v]==0)
    		{
    			dfs(v,a,g,vis);
    			xor[u]=xor[u]^xor[v];
    		}
    	}
    }

	static int[][] packD(int n,int[] from,int[] to)
	{
		int[][] g=new int[n][];
		int[] p=new int[n];
		for(int f:from)
		{
			p[f]++;
		}
		int m=from.length;
		for(int i=0;i<n;i++)
		{
			g[i]=new int[p[i]];
		}
		for(int i=0;i<m;i++)
		{
			g[from[i]][--p[from[i]]]=to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
            //this.ind=ind;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    public void run()
    {
        if(debug)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        try {
			solve();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Thread(null,new TimePass(),"Main",1<<26).start();}

    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(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package sept;

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

public class TimePass implements Runnable {
    InputStream is;
    PrintWriter out;
    String INPUT = "30";
    //boolean debug=false;
    boolean debug=true;
    static long mod=998244353;
    static long mod2=1000000007;

    void solve() throws IOException
	{
    	/*
    	int n=ni(),x=ni();
    	int[] a=na(n);
    	int[] from=new int[2*(n-1)];
    	int[] to=new int[2*(n-1)];
    	int ind=0;
    	for(int i=0;i<n-1;i++)
    	{
    		int u=ni()-1,v=ni()-1;
    		from[ind++]=u;
    		to[ind-1]=v;
    		from[ind++]=v;
    		to[ind-1]=u;
    	}
    	int[][] g=packD(n,from,to);
    	xor=new int[n];
    	int[] vis=new int[n];
    	dfs(0,a,g,vis);
    	if(xor[0]!=0 && xor[0]!=x)
    	{
    		out.println(0);
    		return;
    	}
    	*/
    	/*
    	int q=ni();
    	int[] a=na(q);
    	for(int i=0;i<q;i++)
    	{
    		for(int j=1;j<=Math.sqrt(a[i]);j++)
    		{
    			if(a[i]%j==0)
    			{

    				if(a[i]%(a[i]/j)==0 && j!=a[i]/j)
    				{

    				}
    			}
    		}
    	}
    	*/
    	int n=ni(),m=ni();
    	int[] a=na(n);
    	//Arrays.sort(a);
    	int[] cnt=new int[1000001];
    	for(int i=0;i<n;i++)
    	{
    		cnt[a[i]]++;
    	}
    	long[] dp=new long[1000001];
    	dp[1]=cnt[1]/3;
    	dp[2]=dp[1]+cnt[2]/3;
    	int val=Math.min(cnt[1], Math.min(cnt[2], cnt[3]));
    	dp[3]=Math.max(dp[2]+cnt[3]/3, val+(cnt[1]-val)/3+(cnt[2]-val)/3+(cnt[3]-val)/3);

    	for(int i=4;i<=1000000;i++)
    	{
    		val=Math.min(cnt[i], Math.min(cnt[i-1], cnt[i-2]));
    		dp[i]=Math.max(dp[i-3]+val+(cnt[i]-val)/3+(cnt[i-1]-val)/3+(cnt[i-2]-val)/3,
    				dp[i-1]+cnt[i]/3);
    		dp[i]=Math.max(dp[i], dp[i-2]+cnt[i]/3+cnt[i-1]/3);
    		int val2=Math.min(cnt[i-2]-val, Math.min(cnt[i-1]-val,cnt[i-3]));
    		int v1=cnt[i-3]-val2;
    		int v2=cnt[i-2]-val-val2;
    		int v3=cnt[i-1]-val-val2;
    		dp[i]=Math.max(dp[i], dp[i-4]+val+val2+v1/3+v2/3+v3/3);
    	}
    	out.println(dp[1000000]);
	}

    static int[] xor;

    static void dfs(int u,int[] a,int[][] g,int[] vis)
    {
    	xor[u]=a[u];

    	vis[u]=1;
    	for(int v:g[u])
    	{
    		if(vis[v]==0)
    		{
    			dfs(v,a,g,vis);
    			xor[u]=xor[u]^xor[v];
    		}
    	}
    }

	static int[][] packD(int n,int[] from,int[] to)
	{
		int[][] g=new int[n][];
		int[] p=new int[n];
		for(int f:from)
		{
			p[f]++;
		}
		int m=from.length;
		for(int i=0;i<n;i++)
		{
			g[i]=new int[p[i]];
		}
		for(int i=0;i<m;i++)
		{
			g[from[i]][--p[from[i]]]=to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
            //this.ind=ind;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    public void run()
    {
        if(debug)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        try {
			solve();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Thread(null,new TimePass(),"Main",1<<26).start();}

    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(!oj)System.out.println(Arrays.deepToString(o)); }
}


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1110D
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         int M = Integer.parseInt(st.nextToken());
         int[] arr = new int[N];
         st = new StringTokenizer(infile.readLine());
         for(int i=0; i < N; i++)
            arr[i] = Integer.parseInt(st.nextToken());
         freq = new int[M+1];
         for(int x: arr)
            freq[x]++;
         //solve
         dp = new int[M+1][5][5];
         for(int i=1; i <= M; i++)
            for(int a=0; a < 5; a++)
               Arrays.fill(dp[i][a], -1);
         System.out.println(dfs(M, 0, 0));
      }
      static int[][][] dp;
      static int[] freq;
      public static int dfs(int v, int d1, int d2)
      {
         if(dp[v][d1][d2] != -1)
            return dp[v][d1][d2];
         int res = 0;
         if(v >= 3)
         {
            for(int a=0; a <= 2; a++)
            {
               if(freq[v]-d1-a < 0 || freq[v-1]-d2-a < 0 || freq[v-2]-a < 0)
                  continue;
               res = Math.max(res, a+(freq[v]-a-d1)/3+dfs(v-1, d2+a, a));
            }
         }
         else
            res = dfs(v-1, d2, 0)+(freq[v]-d1)/3;
         return dp[v][d1][d2] = res;
      }
   }


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x1110D2
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int N = Integer.parseInt(st.nextToken());
         int M = Integer.parseInt(st.nextToken());
         int[] arr = new int[N];
         st = new StringTokenizer(infile.readLine());
         for(int i=0; i < N; i++)
            arr[i] = Integer.parseInt(st.nextToken());
         int[] freq = new int[M+1];
         for(int x: arr)
            freq[x]++;
         //dp[0]
         int[][] dp = new int[9][9];
         for(int v=1; v <= M; v++)
         {
            int[][] next = new int[9][9];
            for(int d1=0; d1 <= 4; d1++)
               for(int d2=0; d2 <= 4; d2++)
               {
                  int res = 0;
                  if(v >= 3)
                     for(int a=0; a <= 2; a++)
                     {
                        if(freq[v]-d1-a < 0 || freq[v-1]-d2-a < 0 || freq[v-2]-a < 0)
                           continue;
                        res = Math.max(res, a+(freq[v]-a-d1)/3+dp[d2+a][a]);
                     }
                  else
                     res = Math.max(res, (freq[v]-d1)/3+dp[d2][0]);
                  next[d1][d2] = res;
               }
            dp = next;
         }
         System.out.println(dp[0][0]);
      }
   }


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

public class D {

	static final int INF = Integer.MAX_VALUE / 4;

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

		int[][] dp = new int[4][4];
		for (int[] row : dp) {
			Arrays.fill(row, -INF);
		}
		dp[0][0] = 0;

		for (int i = 4; i < a.length; i++) {
			int[][] nxt = new int[4][4];
			for (int[] row : nxt) {
				Arrays.fill(row, -INF);
			}
			for (int x = 0; x <= 3; x++) {
				for (int y = 0; y <= 3; y++) {
					if (dp[x][y] < 0) {
						continue;
					}
					for (int z = 0; z <= 3; z++) {
						if (x + y + z > a[i - 2] || y + z > a[i - 1] || z > a[i]) {
							continue;
						}
						nxt[y][z] = Math.max(nxt[y][z], dp[x][y] + z + (a[i - 2] - x - y - z) / 3);
					}
				}
			}
			dp = nxt;
		}

		int ans = 0;
		for (int[] row : dp) {
			for (int val : row) {
				ans = Math.max(ans, val);
			}
		}

		out.println(ans);

	}

	void test() {

	}

	void stress() {
		for (int tst = 0;; tst++) {
			if (false) {
				throw new AssertionError();
			}
			System.err.println(tst);
		}
	}

	D() throws IOException {
		is = System.in;
		out = new PrintWriter(System.out);
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();
	static final int C = 5;

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

	public static void main(String[] args) throws IOException {
		new D();
	}

	private InputStream is;
	PrintWriter out;

	private byte[] buf = new byte[1 << 14];
	private int bufSz = 0, bufPtr = 0;

	private int readByte() {
		if (bufSz == -1)
			throw new RuntimeException("Reading past EOF");
		if (bufPtr >= bufSz) {
			bufPtr = 0;
			try {
				bufSz = is.read(buf);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (bufSz <= 0)
				return -1;
		}
		return buf[bufPtr++];
	}

	private boolean isTrash(int c) {
		return c < 33 || c > 126;
	}

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

	String nextToken() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	String nextString() {
		int b = readByte();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b) || b == ' ') {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	char nextChar() {
		return (char) skip();
	}

	int nextInt() {
		int ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}

	long nextLong() {
		long ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}
}


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

public class Main {
    static class InputReader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

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

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

    }

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int n = in.nextInt();
        int m = in.nextInt();

        int[] ints = new int[m + 1];
        int[][][] opt = new int[m + 1][3][3];

        for (int i = 0; i < n; i++) {
            ints[in.nextInt()]++;
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    for (int a = 0; a < 3; a++) {
                        if (a + k + j > ints[i]) {
                        } else if (k + j > ints[i + 1]) {
                        } else if (j > ints[i + 2]) {
                        } else
                            opt[i][j][k] = Math.max(opt[i][j][k],
                                    opt[i - 1][k][a] + j + (ints[i] - j - k - a) / 3);
                    }
                }
            }
        }
        out.println(opt[m][0][0]);
        out.close();
    }
}


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

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);

		int n = in.nextInt();
		int m = in.nextInt();
		int[] count = new int[m + 1];
		for(int i=0; i<n; i++) {
			count[in.nextInt()]++;
		}
		int[][][] opt = new int[2][3][3];
		int num;
		for(int i=1; i<m+1; i++) {
			for(int x=0; x<3; x++) {
				for(int y=0; y<3; y++) {
					opt[0][x][y] = opt[1][x][y];
					opt[1][x][y] = 0;
				}
			}

			for(int j=0; j<3; j++) {
				for(int k=0; k<3; k++) {
					for(int l=0; l<3; l++) {
						num = j + k + l;
						if(count[i] >= num) {
							opt[1][j][k] = Math.max(opt[1][j][k], opt[0][k][l] + j + (count[i] - num)/3);
						}
					}
				}
			}
		}
		out.println(opt[1][0][0]);
		out.close();
	}

	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream), 32768);
			tokenizer = null;
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.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());
		}

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

		public char[] nextCharArray() {
			return next().toCharArray();
		}
	}
}


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

public class Main {
    static class InputReader {
        BufferedReader reader;
        StringTokenizer tokenizer;

        InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

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

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

    }

    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        A.InputReader in = new A.InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);

        int[] cnt = new int[1000010];
        int[][][] dp = new int[1000010][3][3];
        int n = in.nextInt();
        int m = in.nextInt();
        for (int i = 0; i < n; i++) {
            int temp = in.nextInt();
            ++cnt[temp];
        }

        for (int i = 1; i <= m; ++i) {
            for (int c = 0; c < 3; ++c) {
                for (int b = 0; b < 3; ++b) {
                    for (int a = 0; a < 3; ++a) {
                        if (a + b + c > cnt[i]) continue;
                        if (b + c > cnt[i + 1]) continue;
                        if (c > cnt[i + 2]) continue;
                        dp[i][c][b] = Math.max(dp[i][c][b], dp[i - 1][b][a] + c + (cnt[i] - c - b - a) / 3);
                    }
                }
            }
        }
        out.println(dp[m][0][0]);
        out.close();
    }
}


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

import static java.lang.System.in;

public class Main {
    public static void main(String[] args)throws IOException{
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt(), a=0;
        int[] num = new int[m+1];
        for(int i=0;i<n;i++){
            a = sc.nextInt();
            num[a]++;
        }
        int[][][] dp = new int[2][3][3];
        for(int i=1;i<=m;i++){ // outest loop
            for(int k=0;k<3;k++) Arrays.fill(dp[(i+1)%2][k],0);
            for(int j=0;j<3;j++){ // scan through the possible former dp[i][j][k]
                for(int k=0;k<3;k++){
                    for(int L=0;L<3;L++){
                        if(num[i]<j+k+L) continue; // no need to do extra work for num[i]==0
                        int now = dp[i%2][j][k] + (num[i]-j-k-L)/3+L;
                        dp[(i+1)%2][k][L] = Math.max(now,dp[(i+1)%2][k][L]);
                    }
                }
            }
        }
        System.out.println(dp[(m+1)%2][0][0]);
    }
}


import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;

public class Main {
    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null)
                return;
            din.close();
        }
    }

    public static void main(String[] args) throws IOException {
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(System.out);

        int n = in.nextInt();
        int m = in.nextInt();

        int[] ints = new int[m + 20];
        int[][] opt1 = new int[5][5];
        int[][] opt2 = new int[5][5];
        int[][] opt3 = new int[5][5];

        for (int i = 0; i < n; i++) {
            ints[in.nextInt()]++;
        }

        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++) {
                        if (l + k + j <= ints[i]) {
                            opt2[j][k] = Math.max(opt2[j][k],
                                    opt1[k][l] + j + (ints[i] - j - k - l) / 3);
                        }
                    }
                }
            }
            opt1 = opt2.clone();
            opt2 = new int[5][5];
        }
        out.println(opt1[0][0]);
        out.close();

    }
}


import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;

public class Main {
//    static long timeStart = System.currentTimeMillis();
    static long[][][] outcome= new long[1000001][3][3];

    public static void main(String[] args) throws IOException {
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt();
        int max = in.nextInt();
        int[] count = new int[max+3];

        for (int i = 0; i < n ; i++) {
            count[in.nextInt()]++;
        }

        for (int i = 1; i < max + 1; i++) {
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    for (int l = 0; l < 3; l++) {
                        if (j + k + l > count[i]||j + k > count[i + 1]||j > count[i + 2]) continue;
                        long tmp1 = outcome[i][j][k];
                        long tmp2 = outcome[i - 1][k][l] + j + (count[i] - j - k - l) / 3;
                        if (tmp1 > tmp2) outcome[i][j][k] = tmp1;
                        else outcome[i][j][k] = tmp2;
                    }
                }
            }
        }
        out.print(outcome[max][0][0]);
//
//        long timeEnd = System.currentTimeMillis();
//        long timeCost = timeEnd - timeStart;
//        out.print(timeCost + "ms");
        out.close();
    }

    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null)
                return;
            din.close();
        }
    }

}


//快读模板1：更快，但没有next()用于读字符串

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

public class Main {

    public static void main(String[] args) throws IOException {
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt(), m = in.nextInt();
        int maj[] = new int[m + 3];
        for (int i = 0; i < n; i++) {
            maj[in.nextInt()]++;
        }
        int dp[][][] = new int[2][3][3];
        for (int i = 1; i <= m; i++) {
            int current = i % 2;
            int pre = (i + 1) % 2;
            for(int j = 0 ; j < 3 ; j++){
                for(int k = 0 ; k < 3 ; k++){
                    dp[current][j][k] = 0;
                }
            }
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    for (int l = 0; l < 3; l++) {
                        if (maj[i] >= j + k + l && maj[i + 1] >= k + l && maj[i + 2] >= l)
                            dp[current][k][l] = Math.max(dp[current][k][l], dp[pre][j][k] + l + (maj[i] - j - k - l) / 3);
                    }
                }
            }
        }
        System.out.println(dp[m % 2][0][0]);
        out.close();
    }

    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null)
                return;
            din.close();
        }
    }

}


//快读模板1：更快，但没有next()用于读字符串

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

public class Main {

    public static void main(String[] args) throws IOException {
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt(), m = in.nextInt();
        int maj[] = new int[m + 3];
        for (int i = 0; i < n; i++) {
            maj[in.nextInt()]++;
        }
        int dp[][][] = new int[2][3][3];
        for (int i = 1; i <= m; i++) {
            int current = i % 2;
            int pre = (i + 1) % 2;
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    for (int l = 0; l < 3; l++) {
                        if (maj[i] >= j + k + l && maj[i + 1] >= k + l && maj[i + 2] >= l)
                            dp[current][k][l] = Math.max(dp[current][k][l], dp[pre][j][k] + l + (maj[i] - j - k - l) / 3);
                    }
                }
            }
        }
        System.out.println(dp[m % 2][0][0]);
        out.close();
    }

    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null)
                return;
            din.close();
        }
    }

}


//快读模板1：更快，但没有next()用于读字符串

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

public class Main {

    public static void main(String[] args) throws IOException {
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(System.out);
        int n = in.nextInt(), m = in.nextInt();
        int maj[] = new int[m + 3];
        for (int i = 0; i < n; i++) {
            maj[in.nextInt()]++;
        }
        int dp[][][] = new int[2][3][3];
        for (int i = 1; i <= m; i++) {
            int current = i % 2;
            int pre = (i + 1) % 2;
            for(int j = 0 ; j < 3 ; j++){
                for(int k = 0 ; k < 3 ; k++){
                    dp[current[j][k] = 0;
                }
            }
            for (int j = 0; j < 3; j++) {
                for (int k = 0; k < 3; k++) {
                    for (int l = 0; l < 3; l++) {
                        if (maj[i] >= j + k + l && maj[i + 1] >= k + l && maj[i + 2] >= l)
                            dp[current][k][l] = Math.max(dp[current][k][l], dp[pre][j][k] + l + (maj[i] - j - k - l) / 3);
                    }
                }
            }
        }
        System.out.println(dp[m % 2][0][0]);
        out.close();
    }

    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader() {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException {
            din = new DataInputStream(new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n')
                    break;
                buf[cnt++] = (byte) c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException {
            int ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException {
            bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException {
            if (din == null)
                return;
            din.close();
        }
    }

}


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]) 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.*;
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;

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

	private static final byte[] buffer = new byte[1024];
	private static int ptr = 0;
	private static int buflen = 0;
	private static boolean hasNextByte() {
		if (ptr < buflen)  return true;
		else{
			ptr = 0;
			try {
				buflen = System.in.read(buffer);
			} catch (IOException e) {e.printStackTrace();}
			if (buflen <= 0)  return false;
		}
		return true;
	}
	private static int readByte() { return hasNextByte() ? buffer[ptr++] : -1;}
	private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
	private static void skipUnprintable() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;}
	public static boolean hasNext() { skipUnprintable(); return hasNextByte();}
	public static String next() {
		if (!hasNext()) throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		for(int b = readByte();isPrintableChar(b);b = readByte()) {
			sb.appendCodePoint(b);
		}
		return sb.toString();
	}
	public static int nextInt() {return (int)nextLong();}
	public static long nextLong() {
		if (!hasNext()) throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b)  throw new NumberFormatException();
		while(true){
			if ('0' <= b && b <= '9') n = n * 10 + b-'0';
			else if(b == -1 || !isPrintableChar(b)) return minus ? -n : n;
			else throw new NumberFormatException();
			b = readByte();
		}
	}
	public static long[] nextLongArray(int i){
		long[] result=new long[i];
		for(int j=0;j<i;j++)  result[j]=nextLong();
		return result;
	}
	public static void nextLongArray(long[]... arrays){
		for(int j=0;j<arrays[0].length;j++)
			for(long[] array:arrays) array[j]=nextLong();
	}
	public static int[] nextIntArray(int i){
		int[] result=new int[i];
		for(int j=0;j<i;j++)  result[j]=nextInt();
		return result;
	}
	public static void nextIntArray(int[]... arrays){
		for(int j=0;j<arrays[0].length;j++)
			for(int[] array:arrays)  array[j]=nextInt();
	}
	public static int ni(){return nextInt();}
	public static long nl(){return nextLong();}
	public static int[] nia(int n){return nextIntArray(n);}
	public static long[] nla(int n){return nextLongArray(n);}
	public static String ne(){return next();}

	static StringBuilder sb=new StringBuilder();
	public static void flush(){
		System.out.print(sb);
		sb=new StringBuilder();
	}
	public static void pr(Object o){sb.append(o);}
	public static void pl(Object o){sb.append(o).append("\n");}
	public static void pl(){sb.append("\n");}
	public static int lastLowerIndex(long[] array,long lo){return lastLowerOrEqualIndex(array,lo-1);}
	public static int lastLowerOrEqualIndex(long[] array,long lo){
		int res=Arrays.binarySearch(array,lo);
		return res<0?-res-2:res;
	}
	public static long gcd(long a,long b){
		if(a>b)a%=b;
		while(a>0){
			b%=a;
			if(b==0)return a;
			a%=b;
		}
		return b;
	}
	public static long modPow(long a,long b,long mod){
		long c=1;
		while(b>0){
			if(b%2==1)  c=(c*a)%mod;
			a=(a*a)%mod;
			b/=2;
		}
		return c;
	}
	public static long inv(long a,long mod){
		long b=mod;
		long p = 1, q = 0;
		while (b > 0) {
			long c = a / b;
			long d=a;
			a = b;
			b = d % b;
			d = p;
			p = q;
			q = d - c * q;
		}
		return p < 0 ? p + mod : p;
	}
	static long time=0;
	public static void time(){
		if(time==0) time=System.nanoTime();
		else{
			long t=System.nanoTime();
			pl((t-time)/1000000000.0+"sec");
			time=t;
		}
	}
	public static Integer[] sortedIndex(long[] a){
            Integer[] res=new Integer[a.length];
            for(int i=0;i<a.length;i++)	res[i]=i;
            mergesortIndex(res,a,0,a.length);
            return res;
        }
        private static Integer[] stem=new Integer[200005];
        private static void mergesortIndex(Integer[] index,long[] a, int s, int e){
            if(e - s <= 1)return;
            int h = s+e>>1;
            mergesortIndex(index,a, s, h);
            mergesortIndex(index,a, h, e);
            int p = 0;
            int i= s, j = h;
            for(;i < h && j < e;)stem[p++] = a[(int)index[i]] < a[(int)index[j]] ? index[i++] : index[j++];
            while(i < h)stem[p++] = index[i++];
            while(j < e)stem[p++] = index[j++];
            System.arraycopy(stem, 0, index, s, e-s);
        }
        private static long[] stmp=new long[200005];
        private static void mergesort(long[] a, int s, int e){
            if(e - s <= 1)return;
            int h = s+e>>1;
            mergesort(a, s, h);
            mergesort(a, h, e);
            int p = 0;
            int i= s, j = h;
            for(;i < h && j < e;)stmp[p++] = a[i] < a[j] ? a[i++] : a[j++];
            while(i < h)stmp[p++] = a[i++];
            while(j < e)stmp[p++] = a[j++];
            System.arraycopy(stmp, 0, a, s, e-s);
        }
}


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;

    	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);
        }
}