#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <assert.h>
#include <set>
using namespace std;
#define MAXN 3004
#define MAXM 40010
#define HASHMOD 100003
#define INF 0x3f3f3f3f
typedef struct road {
	int fromCity;
	int toCity;
	int NO;
	struct road() {}
	struct road(int u, int v) { fromCity = u; toCity = v; }
	struct road(int u, int v, int No) { fromCity = u; toCity = v; NO = No; }
	bool operator == (struct road r) {
		return (fromCity == r.fromCity&&toCity == r.toCity);
	}
}Road;
typedef struct cancellableVertex {
	int toNode;
	bool valid;
	struct cancellableVertex(int to) { toNode = to; valid = true; }
}CancellableVertex;
typedef struct Vertex {
	int weight;
	bool isValid;
	int pi;
}Vertex;
int allRoads[MAXN][MAXN];
Road roadIndex[MAXM];
vector<int > originalGraph[MAXN];
vector<CancellableVertex > roadGraph[MAXM];
Vertex roadVertices[MAXM];
int n, m, k, indexNumber;
int roadNumber(Road r)
{
	return allRoads[r.fromCity][r.toCity];
}
void input()
{
	memset(allRoads, 0xff, sizeof(allRoads));
	for (int i = 0; i < MAXN; i++)
		originalGraph[i].clear();
	memset(roadIndex, 0xff, sizeof(roadIndex));
	indexNumber = 0;
	for (int i = 0; i < m; i++) {
		int u, v, h;
		scanf("%d %d", &u, &v);
		if (roadNumber(Road(u, v)) < 0) {
			allRoads[u][v] = indexNumber;
			roadIndex[indexNumber] = Road(u, v,indexNumber);
			indexNumber++;
			originalGraph[u].push_back(v);
		}
		if (roadNumber(Road(v, u)) < 0) {
			allRoads[v][u] = indexNumber;
			roadIndex[indexNumber] = Road(v, u,indexNumber);
			indexNumber++;
			originalGraph[v].push_back(u);
		}
	}
	originalGraph[0].push_back(1);
	originalGraph[n].push_back(n+1);
	allRoads[0][1] = indexNumber;
	roadIndex[indexNumber] = Road(0, 1, indexNumber);
	indexNumber++;
	allRoads[n][n+1] = indexNumber;
	roadIndex[indexNumber] = Road(n, n+1, indexNumber);
	indexNumber++;
	//printf("Indexnumber:%d\n", indexNumber);
}
void banRoads()
{
	//time_t start, end;
	//start = time(NULL);
	for (int i = 0; i < k; i++) {
		int u, v, w, h1, h2;
		scanf("%d %d %d", &u, &v, &w);
		h1 = roadNumber(Road(u, v));
		h2 = roadNumber(Road(v, w));
		if (h1 < 0 || h2 < 0)
			continue;
		for(unsigned int j=0;j<roadGraph[h1].size();j++)
			if(roadGraph[h1][j].toNode==h2)
				roadGraph[h1][j].valid = false;
	}
	//end = time(NULL);
	//printf("Ban roads for %.2lf\n", difftime(end, start));
}
void showGraph()
{
	for (int i = 0; i <= n+1; i++) {
		printf("From vertex #%d:",i);
		for (unsigned int j = 0; j < originalGraph[i].size(); j++)
			printf("%d.%d\t", originalGraph[i][j], roadNumber(Road(i, originalGraph[i][j])));
		printf("\n");
	}
	for (int i = 0; i < indexNumber; i++) {
		printf("From road #%d which is %d->%d:", i,roadIndex[i].fromCity,roadIndex[i].toCity);
		for (unsigned int j = 0; j < roadGraph[i].size(); j++) {
			if (roadGraph[i][j].valid)
				printf("%d\t", roadGraph[i][j].toNode);
		}
		printf("\n");
	}
}
void buildRoadGraph()
{
	//time_t end, start;
	//start = time(NULL);
	for (int i = 0; i < MAXM; i++)
		roadGraph[i].clear();
	for (int i = 0; i <= n+1; i++) {
		for (unsigned int j = 0; j < originalGraph[i].size(); j++) {
			int tempRoadNumber = roadNumber(Road(i, originalGraph[i][j]));
			//printf("tempRoadNumber:%d\n", tempRoadNumber);
			int u = originalGraph[i][j];
			for (unsigned int v = 0; v < originalGraph[u].size(); v++) {
				int h = roadNumber(Road(u, originalGraph[u][v]));
				roadGraph[tempRoadNumber].push_back(CancellableVertex(h ));
			}
		}
	}
	//end = time(NULL);
	//printf("Index:%d\n", indexNumber);
	//printf("Build graph for %.2lf on %d %d %d\n", difftime(end, start), n, m, k);
}
int extractMin()
{
	int tempMin = INF;
	int tempMinIndex = -1;
	for (int i = 0; i < indexNumber; i++) {
		if (roadVertices[i].isValid&&roadVertices[i].weight<=tempMin) {
			tempMin = roadVertices[i].weight;
			tempMinIndex = i;
		}
	}
	if (tempMinIndex < 0)
		return tempMinIndex;
	roadVertices[tempMinIndex].isValid = false;
	return tempMinIndex;
}
int allMin;
vector<int > minRoute;
void bfs(int s)
{
	for (int i = 0; i < indexNumber; i++) {
		roadVertices[i].isValid = false;
		roadVertices[i].weight = INF;
		roadVertices[i].pi = -1;
	}
	roadVertices[s].isValid = true;
	roadVertices[s].weight = 0;
	queue<int > vertices;
	while (vertices.empty() == false)
		vertices.pop();
	vertices.push(s);
	while (vertices.empty() == false) {
		int u = vertices.front();
		vertices.pop();
		for (int i = 0; i < roadGraph[u].size(); i++) {
			if (roadGraph[u][i].valid) {
				int v = roadGraph[u][i].toNode;
				if (roadVertices[v].isValid == false) {
					roadVertices[v].isValid = true;
					roadVertices[v].weight = roadVertices[u].weight + 1;
					roadVertices[v].pi = u;
					vertices.push(v);
				}
			}
		}
	}
}
vector<int > routeNumbers;
void getRoute(int s, int t)
{
	if (roadVertices[t].pi == s) {
		routeNumbers.push_back(s);
		routeNumbers.push_back(t);
	}
	else if (roadVertices[t].pi < 0)
		routeNumbers.push_back(s);
	else {
		getRoute(s, roadVertices[t].pi);
		routeNumbers.push_back(t);
	}
}
void getMinRoute(int s, int t)
{
	routeNumbers.clear();
	getRoute(s, t);
	minRoute.clear();
	for (unsigned int i = 0; i < routeNumbers.size(); i++)
		minRoute.push_back(routeNumbers[i]);
}
void prepareData()
{
	FILE *output = fopen("dataPrepare.txt", "w");
	if (output == NULL) {
		perror("Can't open preparedata!\n");
		return;
	}
	srand(time(NULL));
	for (int i = 0; i < 20; i++) {
		int n, m, k;
		n = rand() % 3000;
		if (n < 2)
			n += 2;
		m = rand() % 20000;
		if (m < 1)
			m += 2;
		k = rand() % 100000;
		fprintf(output,"%d %d %d\n", n, m, k);
		for (int i = 0; i < m; i++) {
			int u, v;
			u = rand() % n;
			v = rand() % n;
			if (u == 0)
				u = 1;
			if (v == 0)
				v = 1;
			fprintf(output,"%d %d\n", u, v);
		}
		for (int i = 0; i < k; i++) {
			int u, v, w;
			u = rand() % n;
			v = rand() % n;
			w = rand() % n;
			if (u == 0)
				u = 1;
			if (v == 0)
				v = 1;
			if (w == 0)
				w = 1;
			fprintf(output, "%d %d %d\n", u, v, w);
		}
		fprintf(output, "\n");
	}
	fclose(output);
}
void solveOne(int s)
{
	bfs(s);
	int tempMin = INF;
	int h = roadNumber(Road(n , n+1));
	tempMin = roadVertices[h].weight;
	if (tempMin < allMin) {
		getMinRoute(s, h);
		allMin = tempMin;
	}
	//printf("For solving %d costs %.2lf s\n", s, difftime(end, start));
}
void solve()
{
	allMin = INF;
	int h = roadNumber(Road(0, 1));
	solveOne(h);
	if (allMin == INF)
		printf("-1\n");
	else {
		printf("%d\n", minRoute.size()-2);
		for (unsigned int i = 0; i < minRoute.size()-1; i++) {
			printf("%d%c", roadIndex[minRoute[i]].toCity,i==minRoute.size()-2?'\n':' ');
		}
	}
}
int main()
{
	while (scanf("%d %d %d", &n, &m, &k) != EOF) {
		input();
		buildRoadGraph();
		banRoads();
		solve();
	}
	return 0;
}


#pragma comment(linker,"/STACK:64000000")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <cmath>
#include <map>
#include <set>
#include <ctime>
#include <algorithm>
#include <memory.h>

using namespace std;

#define WR printf
#define RE scanf
#define PB push_back
#define SE second
#define FI first

#define FOR(i,k,n) for(int i=(k); i<=(n); i++)
#define DFOR(i,k,n) for(int i=(k); i>=(n); i--)
#define SZ(a) (int)((a).size())
#define FA(i,v) FOR(i,0,SZ(v)-1)
#define RFA(i,v) DFOR(i,SZ(v)-1,0)
#define CLR(a) memset(a, 0, sizeof(a))

#define LL long long
#define VI  vector<int>
#define PAR pair<int ,int>
#define o_O 1000000000
void __never(int a){printf("\nOPS %d", a);}
#define ass(s) {if (!(s)) {__never(__LINE__);cout.flush();cerr.flush();abort();}}

struct HELEM
{
	int x, y, z;
	HELEM * nxt;
};

struct HASH
{
	HELEM * table[70000];
	HELEM H[200000];
	int sz;
	HASH()
	{
		sz=0;
	}

	void add(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		H[sz].x = x;
		H[sz].y = y;
		H[sz].z = z;
		H[sz].nxt = table[k];
		table[k] = &H[sz];
		sz++;
	}

	bool has(int x, int y, int z)
	{
		int k = (((x + (y<<5) + (z<<10))*(o_O+7))&65535);
		for (HELEM * h = table[k]; h; h = h->nxt)
			if (h->x == x && h->y == y && h->z == z)
				return true;
		return false;
	}
} H;

int n, m, k;
//set< pair< PAR, int > > bad;
/*VI G[41000];*/
PAR E[41000];
int e_sz=0;
int be[3200], en[3200];
int q[41000], pre[41000];
bool F[41000];

bool is_bad(int x, int y, int z)
{
	//return bad.find(make_pair(make_pair(x,y),z)) != bad.end();
	return H.has(x,y,z);
}

void sol()
{
	sort(E,E+e_sz);
	FOR(a,1,n)
	{
		be[a]=o_O;
		en[a]=-1;
	}
	FOR(a,0,e_sz-1)
	{
		be[E[a].first] = min(be[E[a].first], a);
		en[E[a].first] = max(en[E[a].first], a);
	}

	/*FOR(a,0,e_sz-1) FOR(b,be[E[a].second],en[E[a].second])
		if (bad.find(make_pair(E[a],E[b].second)) == bad.end())
			G[a].push_back(b);*/

	int z = 0;
	FOR(a,be[1],en[1])
	{
		if (E[a].second==n)
		{
			WR("1\n");
			WR("%d %d", E[a].first, E[a].second);
			return;
		}
		F[a]=true;
		pre[a]=-1;
		q[z++] = a;
	}

	FOR(a,0,z-1) FOR(b,be[E[q[a]].second],en[E[q[a]].second])
		if (!F[b])
			if (!is_bad(E[q[a]].first,E[q[a]].second,E[b].second))
			{
				F[b]=true;
				pre[b]=q[a];
				q[z++]=b;
				if (E[b].second==n)
				{
					VI ans;
					int i=q[z-1];
					while (i!=-1)
					{
						ans.push_back(E[i].second);
						i=pre[i];
					}
					ans.push_back(1);
					reverse(ans.begin(), ans.end());

					WR("%d\n", SZ(ans)-1);
					FA(c,ans) WR("%d ", ans[c]);
					return;
				}
			}

	WR("-1");
}

int main()
{
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);

	cin >> n >> m >> k;
	FOR(a,1,m)
	{
		int x, y;
		RE("%d%d", &x, &y);
		E[e_sz++] = make_pair(x,y);
		E[e_sz++] = make_pair(y,x);
	}
	FOR(a,1,k)
	{
		int x, y, z;
		RE("%d%d%d", &x, &y, &z);
		//bad.insert(make_pair(make_pair(x,y),z));
		H.add(x,y,z);
	}
	sol();

	return 0;
}


//package Spring2019.Mar2;

import java.util.Scanner;

public class Main {
    static int min(int a, int b, int c) {
        return Math.min(a, Math.min(b, c));
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[] a = new int[m + 3];
        for (int i = 1; i <= n; i++) {
            int x = in.nextInt();
            a[x]++;
        }
        int[][][] f = new int[m + 1][n + 1][n + 1];
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            for (int j = 0; j <= min(a[Math.max(0, i - 2)], a[i - 1], a[i]); j++) {
                for (int k = 0; k <= min(a[i - 1] - j, a[i] - j, a[i + 1]); k++) {
                    for (int l = 0; l <= min(a[i] - j - k, a[i + 1] - k, a[i + 2]); l++) {
                        f[i][k][l] = Math.max(f[i][k][l], f[i - 1][j][k] + (a[i] - j - k - l) / 3 + l);
                        ans = Math.max(ans, f[i][k][l]);
                    }
                }
            }
        }
        System.out.println(ans);
    }
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class TaskD {
	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
		int n = in.nextInt();
		int m = in.nextInt();
		int[] a = getIntArr(in, n);
		int r = solve(n, m, a);
		System.out.println(r);
		in.close();
	}

	private static int solve(int n, int m, int[] a) {
		int[] cnt = new int[m];
		for (int i = 0; i < a.length; i++) {
			cnt[a[i] - 1]++;
		}
		int[][] dp = new int[3][3];
		for (int c : cnt) {
			int[][] new_dp = new int[3][3];
			for (int cntAsLast = 0; cntAsLast < 3; cntAsLast++) {
				for (int cntAsMiddle = 0; cntAsMiddle < 3; cntAsMiddle++) {
					for (int cntAsFirst = 0; cntAsFirst < 3; cntAsFirst++) {
						if (cntAsLast + cntAsMiddle + cntAsFirst <= c) {
							new_dp[cntAsMiddle][cntAsFirst] = Math.max(new_dp[cntAsMiddle][cntAsFirst], dp[cntAsLast][cntAsMiddle] + cntAsFirst + (c - cntAsLast - cntAsMiddle - cntAsFirst) / 3);
						}
					}
				}
			}
			int[][] tmp = new_dp;
			new_dp = dp;
			dp = tmp;
		}
		return dp[0][0];
	}

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

	static String str(int[] a) {
		String[] str = new String[a.length];
		for (int i = 0; i < a.length; i++) {
			str[i] = a[i] + "";
		}
		return String.join(" ", str);
	}

	static int[] getIntArr(Scanner in, int size) {
		int[] arr = new int[size];
		for (int i = 0; i < size; i++) {
			arr[i] = in.nextInt();
		}
		return arr;
	}

	static int[][] getIntArr(Scanner in, int row, int col) {
		int[][] arr = new int[row][];
		for (int i = 0; i < row; i++) {
			arr[i] = getIntArr(in, col);
		}
		return arr;
	}

	static char[] getCharArr(Scanner in, int size) {
		char[] arr = in.next().toCharArray();
		return arr;
	}

	static String[] getStringArr(Scanner in, int size) {
		String[] arr = new String[size];
		for (int i = 0; i < size; i++) {
			arr[i] = in.next();
		}
		return arr;
	}

	static Map<Integer, List<Integer>> getEdges(Scanner in, int size, boolean directed) {
		Map<Integer, List<Integer>> edges = new HashMap<>();
		for (int i = 0; i < size; i++) {
			int from = in.nextInt();
			int to = in.nextInt();
			if (!edges.containsKey(from)) {
				edges.put(from, new ArrayList<Integer>());
			}
			edges.get(from).add(to);
			if (!directed) {
				if (!edges.containsKey(to)) {
					edges.put(to, new ArrayList<Integer>());
				}
				edges.get(to).add(from);
			}

		}
		return edges;
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
/*
 */
public class D {

	static int[] cs;
	static int max;
	static int oo=1_000_000_000;
	static int[][][] dp;

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		max=fs.nextInt();
		cs=new int[max+2];
		dp=new int[2][5][5];
		for (int i=0; i<n; i++) cs[fs.nextInt()-1]++;

		for (int ind=max; ind>=0; ind--) {
			for (int i=0; i<5; i++) {
				for (int j=0; j<5; j++) {
					dp[(ind&1)][i][j]=-1;
					go(ind, i, j);
				}
			}
		}
		int ans=go(0, 0, 0);
		System.out.println(ans);
	}

	static int go(int index, int timesUsed, int nextUsed) {
		if (index==max) {
			if (timesUsed==0 && nextUsed==0) {
				return 0;
			}
			else {
				return -oo;
			}
		}
		if (timesUsed>=5 || nextUsed>=5) {
			return -oo;
		}
		if (dp[index&1][timesUsed][nextUsed]!=-1) return dp[index&1][timesUsed][nextUsed];
		int best=-oo;
		for (int take=0; take<3; take++) {
			int nextMe=cs[index]-timesUsed-take;
			if (nextMe<0) continue;
			int ans=go(index+1, nextUsed+take, take)+take+nextMe/3;
			best=Math.max(best, ans);
		}
		return dp[index&1][timesUsed][nextUsed]=best;
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");

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

		}

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

		public int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}

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

		public long[] readLongArray(int n) {
			long[] a=new long[n];
			for (int i=0; i<n; i++) a[i]=nextLong();
			return a;
		}
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.StringTokenizer;
/*
 */
public class D {

	static int[] cs;
	static int max;
	static int oo=1_000_000_000;
	static int[][][] dp;

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		max=fs.nextInt();
		cs=new int[max+2];
		dp=new int[max+2][5][5];
		for (int i=0; i<dp.length; i++)
			for (int j=0; j<dp[i].length;j++)
				Arrays.fill(dp[i][j], -1);
		for (int i=0; i<n; i++) cs[fs.nextInt()-1]++;
		int ans=go(0, 0, 0);
		System.out.println(ans);
	}

	static int go(int index, int timesUsed, int nextUsed) {
		if (index==max) {
			if (timesUsed==0 && nextUsed==0) {
				return 0;
			}
			else {
				return -oo;
			}
		}
		if (timesUsed>=5 || nextUsed>=5) {
			return -oo;
		}
		if (dp[index][timesUsed][nextUsed]!=-1) return dp[index][timesUsed][nextUsed];
		int best=-oo;
		for (int take=0; take<3; take++) {
			int nextMe=cs[index]-timesUsed-take;
			if (nextMe<0) continue;
			int ans=go(index+1, nextUsed+take, take)+take+nextMe/3;
			best=Math.max(best, ans);
		}
		return dp[index][timesUsed][nextUsed]=best;
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");

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

		}

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

		public int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}

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

		public long[] readLongArray(int n) {
			long[] a=new long[n];
			for (int i=0; i<n; i++) a[i]=nextLong();
			return a;
		}
	}

}


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

public class D {

	static int[][][] dp;
	static int[] cs;
	static int oo=1_000_000_00, m;

	public static void main(String[] args) {
		Thread t=new Thread(null, null, "T", 1<<28) {
			public void run() {
				new D();
			}
		};
		t.start();
	}
	public D() {
		FastScanner fs=new FastScanner();
		int n=fs.nextInt();
		m=fs.nextInt();
		int[] a=fs.readArray(n);
		cs=new int[m+10];
		for (int i:a) cs[i-1]++;

		dp=new int[4][4][m+10];
		for (int i=0; i<dp.length; i++)
			for (int j=0; j<dp[i].length; j++)
				Arrays.fill(dp[i][j], -1);
		int ans=go(0, 0, 0);
		System.out.println(ans);
	}

	static int go(int pairs1Before, int pairs2Before, int index) {
		if (index==m) {
			if (pairs1Before>0||pairs2Before>0)
				return -oo;
			return 0;
		}
		if (dp[pairs1Before][pairs2Before][index]!=-1)
			return dp[pairs1Before][pairs2Before][index];
		int usedAlready=pairs1Before+pairs2Before;
		if (usedAlready>cs[index])
			return dp[pairs1Before][pairs2Before][index]=-oo;
		int maxToStart=Math.min(3, cs[index]-usedAlready);
		int best=-oo;
		for (int toStart=0; toStart<=maxToStart; toStart++) {
			int next1Before=toStart;
			int next2Before=pairs1Before;
			int tripleBonus=(cs[index]-usedAlready-toStart)/3;
			int score=tripleBonus+toStart+go(next1Before, next2Before, index+1);
			best=Math.max(best, score);
		}
		return dp[pairs1Before][pairs2Before][index]=best;
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");

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

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

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

		public int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) {
				a[i]=nextInt();
			}
			return a;
		}

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

	}

}


//package codeforces;
import java.util.*;

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


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
    InputStream is;

    int __t__ = 1;
    int __f__ = 0;
    int __FILE_DEBUG_FLAG__ = __f__;
    String __DEBUG_FILE_NAME__ = "src/D1";

    FastScanner in;
    PrintWriter out;

    public void solve() {
        int n = in.nextInt();
        int m = in.nextInt();

        int[] cnt = new int[m];
        int[][] dp = new int[m+1][15];
        for (int i = 0; i <= m; i++) {
            Arrays.fill(dp[i], -1);
        }
        dp[0][0] = 0;
        for (int i = 0; i < n; i++) {
            int a = in.nextInt();
            cnt[a-1]++;
        }

        for (int i = 0; i < m; i++) {
            for (int p1 = 0; p1 < 5; p1++) for (int p2 = 0; p2 < 3; p2++) {
                int j = p1 * 3 + p2;
                if (dp[i][j] == -1) continue;

                // s = 0
                {
                    int nj = p2 * 3;
                    dp[i+1][nj] = Math.max(dp[i+1][nj], dp[i][j] + (cnt[i] - p1) / 3);
                }
                for (int s = 1; s < 3; s++) {
                    if (i + 2 >= m || cnt[i] < s + p1 || cnt[i+1] < s + p2 || cnt[i+2] < s) {
                        continue;
                    }
                    int nj = (p2 + s) * 3 + s;
                    dp[i+1][nj] = Math.max(dp[i+1][nj], dp[i][j] + s + (cnt[i] - s - p1) / 3);
                }
            }
        }
        int res = 0;
        for (int i = 0; i < dp[m].length; i++) {
            res = Math.max(res, dp[m][i]);
        }
        System.out.println(res);
    }

    public void run() {
        if (__FILE_DEBUG_FLAG__ == __t__) {
            try {
                is = new FileInputStream(__DEBUG_FILE_NAME__);
            } catch (FileNotFoundException e) {
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
            System.out.println("FILE_INPUT!");
        } else {
            is = System.in;
        }
        in = new FastScanner(is);
        out = new PrintWriter(System.out);

        solve();
    }

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

    class FastScanner {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public FastScanner(InputStream stream) {
            this.stream = stream;
            // stream = new FileInputStream(new File("dec.in"));

        }

        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++];
        }

        boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        boolean isEndline(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

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

        int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; i++)
                array[i] = nextInt();

            return array;
        }

        int[][] nextIntMap(int n, int m) {
            int[][] map = new int[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextIntArray(m);
            }
            return map;
        }

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

        long[] nextLongArray(int n) {
            long[] array = new long[n];
            for (int i = 0; i < n; i++)
                array[i] = nextLong();

            return array;
        }

        long[][] nextLongMap(int n, int m) {
            long[][] map = new long[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextLongArray(m);
            }
            return map;
        }

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

        double[] nextDoubleArray(int n) {
            double[] array = new double[n];
            for (int i = 0; i < n; i++)
                array[i] = nextDouble();

            return array;
        }

        double[][] nextDoubleMap(int n, int m) {
            double[][] map = new double[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = in.nextDoubleArray(m);
            }
            return map;
        }

        String next() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        String[] nextStringArray(int n) {
            String[] array = new String[n];
            for (int i = 0; i < n; i++)
                array[i] = next();

            return array;
        }

        String nextLine() {
            int c = read();
            while (isEndline(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndline(c));
            return res.toString();
        }
    }
}


//package com.company;

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

public class Main {
    public static class Task {

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] arr = new int[m + 2];
            for (int i = 0; i < n; i++) {
                int a = sc.nextInt() - 1;
                arr[a]++;
            }
            int[][] dp = new int[5][5]; // prev prev, prev
            for (int i = 0; i < 5; i++) {
                Arrays.fill(dp[i], Integer.MIN_VALUE / 2);
            }
            dp[0][0] = 0;
            for (int i = 0; i < m; i++) {
//                int next1 = arr[i + 1];
//                int next2 = arr[i + 2];
                int[][] nextDp = new int[5][5];
                for (int j = 0; j < 5; j++) {
                    for (int k = 0; k < 5; k++) {
                        nextDp[j][k] = Integer.MIN_VALUE / 2;
                    }
                }
                for (int prev2 = 0; prev2 < 5; prev2++) {
                    for (int prev1 = 0; prev1 < 5; prev1++) {
                        int cur = arr[i];
                        if (dp[prev2][prev1] >= 0) {
                            for (int l = 0; l <= Math.min(cur, Math.min(prev2, prev1)); l++) {
                                int c2 = prev2 - l;
                                int c1 = prev1 - l;
                                int c0 = cur - l;
                                int gain = l;
                                gain += c2 / 3;
                                c2 -= (c2 / 3) * 3;
                                if (c0 >= 5) {
                                    gain += (c0 - 2) / 3;
                                    c0 -= (c0 - 2) / 3 * 3;
                                }
                                nextDp[c1][c0] = Math.max(nextDp[c1][c0], gain + dp[prev2][prev1]);
//                                if (nextDp[c1][c0] > 0) {
//                                    pw.println(prev2 + " " + prev1);
//                                }
                            }
                        }
                    }
                }
//                for (int j = 0; j < 5; j++) {
//                    for (int k = 0; k < 5; k++) {
//                        pw.print(nextDp[j][k] + " ");
//                    }
//                    pw.println();
//                }
//                pw.println();
                dp = nextDp;
            }
            int bext = 0;
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    bext = Math.max(bext, dp[i][j]);
                }
            }
            pw.println(bext);

        }

    }

    private static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("froggy.in"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("froggy.out"));

//        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.in"));
        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
//        System.out.println("Memory increased:" + (usedMemoryAfter-usedMemoryBefore) / 1000000 );
//        System.out.println("Time used: " + (TIME_END - TIME_START) + ".");
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream s){  br = new BufferedReader(new InputStreamReader(s));}

        public Scanner(FileReader s) throws FileNotFoundException {br = new BufferedReader(s);}

        public String next() throws IOException
        {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

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

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

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

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

        public boolean ready() throws IOException {return br.ready();}
    }
}


//package com.company;

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

public class Main {
    public static class Task {
        static final int size = 5;
        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] arr = new int[m + 2];
            for (int i = 0; i < n; i++) {
                int a = sc.nextInt() - 1;
                arr[a]++;
            }
            int[][] dp = new int[size][size]; // prev prev, prev
            for (int i = 0; i < 5; i++) {
                Arrays.fill(dp[i], Integer.MIN_VALUE / 2);
            }
            dp[0][0] = 0;
            for (int i = 0; i < m; i++) {
                int[][] nextDp = new int[size][size];
                for (int j = 0; j < size; j++) {
                    for (int k = 0; k < size; k++) {
                        nextDp[j][k] = Integer.MIN_VALUE / 2;
                    }
                }
                nextDp[0][0] = dp[0][0];
                for (int prev2 = 0; prev2 < size; prev2++) {
                    for (int prev1 = 0; prev1 < size; prev1++) {
                        int cur = arr[i];
                        if (dp[prev2][prev1] >= 0) {
                            for (int l = 0; l <= Math.min(cur, Math.min(prev2, prev1)); l++) {
                                int c2 = prev2 - l;
                                int c1 = prev1 - l;
                                int c0 = cur - l;
                                int gain = l;
                                gain += c2 / 3;
//                                c2 -= (c2 / 3) * 3;
                                if (c0 >= size) {
                                    nextDp[c1][size - 1] = Math.max(nextDp[c1][size - 1], gain + dp[prev2][prev1]);
                                    gain += (c0 - (size - 3)) / 3;
                                    c0 -= (c0 - (size - 3)) / 3 * 3;
                                }
                                nextDp[c1][c0] = Math.max(nextDp[c1][c0], gain + dp[prev2][prev1]);
                            }
                        }
                    }
                }
                dp = nextDp;
            }
            int bext = 0;
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    int cnt = dp[i][j];
                    if (i >= 3) cnt += 1;
                    if (j >= 3) cnt += 1;
                    bext = Math.max(bext, cnt);
                }
            }
            pw.println(bext);

        }

    }

    private static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("froggy.in"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("froggy.out"));

//        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.in"));
        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
//        System.out.println("Memory increased:" + (usedMemoryAfter-usedMemoryBefore) / 1000000 );
//        System.out.println("Time used: " + (TIME_END - TIME_START) + ".");
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream s){  br = new BufferedReader(new InputStreamReader(s));}

        public Scanner(FileReader s) throws FileNotFoundException {br = new BufferedReader(s);}

        public String next() throws IOException
        {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

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

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

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

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

        public boolean ready() throws IOException {return br.ready();}
    }
}


//package com.company;

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

public class Main {
    public static class Task {

        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int[] arr = new int[m + 2];
            for (int i = 0; i < n; i++) {
                int a = sc.nextInt() - 1;
                arr[a]++;
            }
            int[][] dp = new int[5][5]; // prev prev, prev
            for (int i = 0; i < 5; i++) {
                Arrays.fill(dp[i], Integer.MIN_VALUE / 2);
            }
            dp[0][0] = 0;
            for (int i = 0; i < m; i++) {
                int[][] nextDp = new int[5][5];
                for (int j = 0; j < 5; j++) {
                    for (int k = 0; k < 5; k++) {
                        nextDp[j][k] = Integer.MIN_VALUE / 2;
                    }
                }
//                nextDp[0][0] = dp[0][0];
                for (int prev2 = 0; prev2 < 5; prev2++) {
                    for (int prev1 = 0; prev1 < 5; prev1++) {
                        int cur = arr[i];
                        if (dp[prev2][prev1] >= 0) {
                            for (int l = 0; l <= Math.min(cur, Math.min(prev2, prev1)); l++) {
                                int c2 = prev2 - l;
                                int c1 = prev1 - l;
                                int c0 = cur - l;
                                int gain = l;
                                gain += c2 / 3;
                                c2 -= (c2 / 3) * 3;
                                if (c0 >= 5) {
                                    gain += (c0 - 2) / 3;
                                    c0 -= (c0 - 2) / 3 * 3;
                                }
                                nextDp[c1][c0] = Math.max(nextDp[c1][c0], gain + dp[prev2][prev1]);
                            }
                        }
                    }
                }
                dp = nextDp;
            }
            int bext = 0;
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    int cnt = dp[i][j];
                    if (i >= 3) cnt += 1;
                    if (j >= 3) cnt += 1;
                    bext = Math.max(bext, cnt);
                }
            }
            pw.println(bext);

        }

    }

    private static long TIME_START, TIME_END;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("froggy.in"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("froggy.out"));

//        PrintWriter pw = new PrintWriter(new FileOutputStream("Test.in"));
        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
//        System.out.println("Memory increased:" + (usedMemoryAfter-usedMemoryBefore) / 1000000 );
//        System.out.println("Time used: " + (TIME_END - TIME_START) + ".");
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream s){  br = new BufferedReader(new InputStreamReader(s));}

        public Scanner(FileReader s) throws FileNotFoundException {br = new BufferedReader(s);}

        public String next() throws IOException
        {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

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

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

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

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

        public boolean ready() throws IOException {return br.ready();}
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * Created by timur on 28.03.15.
 */

public class TaskD {
    boolean eof;
    BufferedReader br;
    StringTokenizer st;
    PrintWriter out;

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

    public String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return "-1";
            }
        }
        return st.nextToken();
    }

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

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

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

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

    void run() throws IOException {
        InputStream input = System.in;
        PrintStream output = System.out;
        try {
            File f = new File("a.in");
            if (f.exists() && f.canRead()) {
                input = new FileInputStream(f);
                output = new PrintStream("a.out");
            }
        } catch (Throwable e) {
        }
        br = new BufferedReader(new InputStreamReader(input));
        out = new PrintWriter(output);
        solve();
        br.close();
        out.close();
    }

    static class ArrayUtils {
        public static void fill(int[][] array, int value) {
            for (int[] row : array) {
                Arrays.fill(row, value);
            }
        }

    }

    void solve() {
        int n = nextInt(), m = nextInt();
        int[] a = new int[m + 3];
        for (int i = 0; i < n; i++) {
            a[nextInt() - 1]++;
        }

//        int[][] current = new int[3][3];
//        int[][] next = new int[3][3];
//        for (int i = 0; i < m; i++) {
//            ArrayUtils.fill(next, 0);
//            for (int j = 0; j < 3; j++) {
//                for (int k = 0; k < 3; k++) {
//                    int at = a[i] - j - k;
//                    int at1 = 0;
//                    if (i + 1 < m) {
//                        at1 = a[i + 1] - k;
//                    }
//                    int at2 = 0;
//                    if (i + 2 < m) {
//                        at2 = a[i + 2];
//                    }
//                    int max = Math.min(at1, Math.min(at2, at));
//                    for (int l = 0; l < 3 && l <= max; l++) {
//                        next[k][l] = Math.max(next[k][l], current[j][k] + l + (at - l) / 3);
//                    }
//                }
//            }
//            int[][] temp = current;
//            out.print((i + 1) + " ");
//            for (int j = 0; j < 3; j++) {
//                for (int k = 0; k < 3; k++) {
//                    out.print(next[j][k] + " ");
//                }
//            }
//            out.println();
//            current = next;
//            next = temp;
//        }
//        out.print(current[0][0]);
//        out.println();
//        out.println();

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

//        dp[0][0][0] = a[0] / 3;
        for (int i = 0; i <= m; i++) {
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][0][0] + a[i] / 3);
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][1][0] + (a[i] - 1) / 3);
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][2][0] + (a[i] - 2) / 3);
//
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][0][1] + a[i] / 3);
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][1][1] + (a[i] - 2) / 3);
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][2][1] + (a[i] - 3) / 3);
//
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][0][2] + a[i] / 3);
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][1][2] + (a[i] - 3) / 3);
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][2][2] + (a[i] - 4) / 3);

//            for (int ki = 1; ki < m; ki++) {
//                out.print((ki + 1) + "asdfasdfasf ");
//                for (int j = 0; j < 3; j++) {
//                    for (int k = 0; k < 3; k++) {
//                        out.print(dp[ki][j][k] + " ");
//                    }
//                }
//                out.println();
//            }
//            out.println();

            for (int ones = 0; ones < 3; ones++) {
//                for (int tres = 1; tres <= Math.min(2, a[i] - ones); tres++) {
//                    if (a[i + 1] >= tres && a[i + 2] >= tres) {
//                        dp[i + 1][0][tres] = Math.max(dp[i + 1][0][tres], dp[i][ones][0] + tres);
//                    }
//                }
                for (int doubs = 0; doubs < 3; doubs++) {
                    for (int tres = 0; tres <= Math.min(2, a[i] - ones - doubs); tres++) {
                        if (a[i + 1] >= doubs + tres && a[i + 2] >= tres) {
                            dp[i + 1][doubs][tres] = Math.max(dp[i + 1][doubs][tres], dp[i][ones][doubs] +
                                (a[i] - ones - doubs - tres) / 3 + tres);
                        }
                    }
                }
            }

//            for (int ki = 0; ki <= m; ki++) {
//                out.print((ki + 1) + " ");
//                for (int j = 0; j < 3; j++) {
//                    for (int k = 0; k < 3; k++) {
//                        out.print(dp[ki][j][k] + " ");
//                    }
//                }
//                out.println();
//            }
//            out.println();

        }
        int ans = 0;
        for (int ones = 0; ones < 3; ones++) {
            ans = Math.max(ans, dp[m][ones][0]);
        }
        out.print(ans);
    }

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * Created by timur on 28.03.15.
 */

public class TaskD {
    boolean eof;
    BufferedReader br;
    StringTokenizer st;
    PrintWriter out;

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

    public String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return "-1";
            }
        }
        return st.nextToken();
    }

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

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

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

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

    void run() throws IOException {
        InputStream input = System.in;
        PrintStream output = System.out;
        try {
            File f = new File("a.in");
            if (f.exists() && f.canRead()) {
                input = new FileInputStream(f);
                output = new PrintStream("a.out");
            }
        } catch (Throwable e) {
        }
        br = new BufferedReader(new InputStreamReader(input));
        out = new PrintWriter(output);
        solve();
        br.close();
        out.close();
    }

    static class ArrayUtils {
        public static void fill(int[][] array, int value) {
            for (int[] row : array) {
                Arrays.fill(row, value);
            }
        }

    }

    void solve() {
        int n = nextInt(), m = nextInt();
        int[] a = new int[m + 3];
        for (int i = 0; i < n; i++) {
            a[nextInt() - 1]++;
        }
        int[][][] dp = new int[m + 3][3][3];

//        dp[0][0][0] = a[0] / 3;
        for (int i = 0; i < m; i++) {
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][0][0] + a[i] / 3);
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][1][0] + (a[i] - 1) / 3);
//            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][2][0] + (a[i] - 2) / 3);
//
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][0][1] + a[i] / 3);
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][1][1] + (a[i] - 2) / 3);
//            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][2][1] + (a[i] - 3) / 3);
//
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][0][2] + a[i] / 3);
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][1][2] + (a[i] - 3) / 3);
//            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][2][2] + (a[i] - 4) / 3);

//            for (int ki = 1; ki < m; ki++) {
//                out.print((ki + 1) + "asdfasdfasf ");
//                for (int j = 0; j < 3; j++) {
//                    for (int k = 0; k < 3; k++) {
//                        out.print(dp[ki][j][k] + " ");
//                    }
//                }
//                out.println();
//            }
//            out.println();

            for (int ones = 0; ones < 3; ones++) {
//                for (int tres = 1; tres <= Math.min(2, a[i] - ones); tres++) {
//                    if (a[i + 1] >= tres && a[i + 2] >= tres) {
//                        dp[i + 1][0][tres] = Math.max(dp[i + 1][0][tres], dp[i][ones][0] + tres);
//                    }
//                }
                for (int doubs = 0; doubs < 3; doubs++) {
                    for (int tres = 0; tres <= Math.min(2, a[i] - ones - doubs); tres++) {
                        if (a[i + 1] >= doubs + tres && a[i + 2] >= tres) {
                            dp[i + 1][doubs][tres] = Math.max(dp[i + 1][doubs][tres], dp[i][ones][doubs] +
                                (a[i] - ones - doubs - tres) / 3 + tres);
                        }
                    }
                }
            }

//            for (int ki = 0; ki < m; ki++) {
//                out.print((ki + 1) + " ");
//                for (int j = 0; j < 3; j++) {
//                    for (int k = 0; k < 3; k++) {
//                        out.print(dp[ki][j][k] + " ");
//                    }
//                }
//                out.println();
//            }
//            out.println();

        }
        int ans = 0;
        for (int ones = 0; ones < 3; ones++) {
            ans = Math.max(ans, dp[m - 1][ones][0]);
        }
        out.print(ans);
    }

}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.TreeSet;

/**
 * Created by timur on 28.03.15.
 */

public class TaskD {
    boolean eof;
    BufferedReader br;
    StringTokenizer st;
    PrintWriter out;

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

    public String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return "-1";
            }
        }
        return st.nextToken();
    }

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

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

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

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

    void run() throws IOException {
        InputStream input = System.in;
        PrintStream output = System.out;
        try {
            File f = new File("a.in");
            if (f.exists() && f.canRead()) {
                input = new FileInputStream(f);
                output = new PrintStream("a.out");
            }
        } catch (Throwable e) {
        }
        br = new BufferedReader(new InputStreamReader(input));
        out = new PrintWriter(output);
        solve();
        br.close();
        out.close();
    }

    void solve() {
        int n = nextInt(), m = nextInt();
        int[] a = new int[m + 3];
        for (int i = 0; i < n; i++) {
            a[nextInt() - 1]++;
        }

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

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                dp[0][i][j] = -20000000;
            }
        }
        dp[0][0][0] = a[0] / 3;
        for (int i = 1; i < m; i++) {
            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][0][0] + a[i] / 3);
            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][1][0] + (a[i] - 1) / 3);
            dp[i][0][0] = Math.max(dp[i][0][0], dp[i - 1][2][0] + (a[i] - 2) / 3);

            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][0][1] + a[i] / 3);
            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][1][1] + (a[i] - 2) / 3);
            dp[i][1][0] = Math.max(dp[i][1][0], dp[i - 1][2][1] + (a[i] - 3) / 3);

            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][0][2] + a[i] / 3);
            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][1][2] + (a[i] - 3) / 3);
            dp[i][2][0] = Math.max(dp[i][2][0], dp[i - 1][2][2] + (a[i] - 4) / 3);

            for (int ones = 0; ones < 3; ones++) {
                for (int tres = 1; tres <= Math.min(2, a[i] - ones); tres++) {
                    if (a[i + 1] >= tres && a[i + 2] >= tres) {
                        dp[i + 1][0][tres] = Math.max(dp[i + 1][0][tres], dp[i][ones][0] + tres);
                    }
                }
                for (int doubs = 1; doubs < 3; doubs++) {
                    for (int tres = 1; tres <= Math.min(2, a[i] - ones - doubs); tres++) {
                        if (a[i + 1] >= doubs + tres && a[i + 2] >= tres) {
                            dp[i + 1][doubs][tres] = Math.max(dp[i + 1][doubs][tres], dp[i][ones][doubs] +
                                (a[i] - ones - doubs - tres) / 3 + tres);
                        }
                    }
                }
            }

        }
        int ans = 0;
        for (int ones = 0; ones < 3; ones++) {
            ans = Math.max(ans, dp[m - 1][ones][0]);
        }
        out.print(ans);
    }

}


/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main implements Runnable{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static ArrayList<Long> factorial;
    static HashSet<Pair> graph[];
/****************************************Solutions Begins***************************************/
    static int input[],freq[],n,m;
    static int dp[][][];
    static int dfs(int i,int x,int y){
        if(i==m+1){
            if(x==0&&y==0)
                return 0;
            else
                return Integer.MIN_VALUE/5;
        }
        if(dp[i][x][y]!=-1){
            return dp[i][x][y];
        }
        if(freq[i]-x-y<0){
            return Integer.MIN_VALUE/5;
        }
        int rem=freq[i]-x-y;
        int a1=Integer.MIN_VALUE;
        for(int j=0;j<=Math.min(2,rem);j++){
            a1=Math.max(a1,(rem-j)/3+j+dfs(i+1,j,x));
        }
        //debug(i,x,y,a1);
        dp[i][x][y]=a1;
        return dp[i][x][y];
    }
    public static void main (String[] args) throws Exception {
        new Thread(null, new Main(), "Main", 1<<26).start();
    }
    public void run() {
    try{
        //do your work here
        String st[]=br.readLine().split(" ");
        n=Integer.parseInt(st[0]);
        m=Integer.parseInt(st[1]);
        st=br.readLine().split(" ");
        input=new int[n];
        freq=new int[m+1];
       // debug(freq);
        for(int i=0;i<n;i++){
            input[i]=Integer.parseInt(st[i]);
            freq[input[i]]++;
        }
        //debug(freq);
        dp=new int[m+1][3][3];
        for(int arr[][]:dp){
            for(int ar[]:arr){
                Arrays.fill(ar,-1);
            }
        }
        int ans=dfs(1,0,0);
        out.println(ans);
    }
        catch(Exception E){}
/*    public static void main (String[] args) throws Exception {
        String st[]=br.readLine().split(" ");
        n=Integer.parseInt(st[0]);
        m=Integer.parseInt(st[1]);
        st=br.readLine().split(" ");
        input=new int[n];
        freq=new int[m+1];
       // debug(freq);
        for(int i=0;i<n;i++){
            input[i]=Integer.parseInt(st[i]);
            freq[input[i]]++;
        }
        //debug(freq);
        dp=new int[m+1][3][3];
        for(int arr[][]:dp){
            for(int ar[]:arr){
                Arrays.fill(ar,-1);
            }
        }
        int ans=dfs(1,0,0);
        out.println(ans);*/
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }

/****************************************Template Begins************************************************/
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.00000000000000000");
        out.println(ft.format(d));
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            if(p1.u!=p2.u){
                return p1.u-p2.u;
            }
            else{
                return p2.v-p1.v;
            }
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }

        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }

        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }

        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }

        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long aa=p2.u-p1.u;
            if(aa<0){
                return -1;
            }
            else if(aa>0){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pair> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pair other = (Pair) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pair other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}


/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static ArrayList<Long> factorial;
    static HashSet<Pair> graph[];
/****************************************Solutions Begins***************************************/
    static int input[],freq[],n,m;
    static int dp[][][];
    static int dfs(int i,int x,int y){
        if(i==m+1){
            if(x==0&&y==0)
                return 0;
            else
                return Integer.MIN_VALUE/5;
        }
        if(dp[i][x][y]!=-1){
            return dp[i][x][y];
        }
        if(freq[i]-x-y<0){
            return Integer.MIN_VALUE/5;
        }
        int rem=freq[i]-x-y;
        int a1=Integer.MIN_VALUE;
        for(int j=0;j<=Math.min(2,rem);j++){
            a1=Math.max(a1,(rem-j)/3+j+dfs(i+1,j,x));
        }
        //debug(i,x,y,a1);
        dp[i][x][y]=a1;
        return dp[i][x][y];
    }
    public static void main (String[] args) throws Exception {
        String st[]=br.readLine().split(" ");
        n=Integer.parseInt(st[0]);
        m=Integer.parseInt(st[1]);
        st=br.readLine().split(" ");
        input=new int[n];
        freq=new int[m+1];
       // debug(freq);
        for(int i=0;i<n;i++){
            input[i]=Integer.parseInt(st[i]);
            freq[input[i]]++;
        }
        //debug(freq);
        dp=new int[m+2][3][3];
       /* for(int arr[][]:dp){
            for(int ar[]:arr){
                Arrays.fill(ar,-1);
            }
        }*/
        for(int j=0;j<=2;j++){
            for(int k=0;k<=2;k++){
                if(j==0&&k==0)
                    dp[m+1][j][k]=0;
                else
                    dp[m+1][j][k]=Integer.MIN_VALUE;
            }
        }
        for(int i=m;i>=1;i--){
            for(int j=0;j<=2;j++){
                for(int k=0;k<=2;k++){
                    int rem=freq[i]-j-k;
                    if(rem<0){
                        dp[i][j][k]=Integer.MIN_VALUE/5;
                        continue;
                    }
                    int a1=Integer.MIN_VALUE;
                    for(int t=0;t<=Math.min(rem,2);t++){
                        a1=Math.max(a1,dp[i+1][t][j]+t+(rem-t)/3);
                    }
                    dp[i][j][k]=a1;
                }
            }
        }
        int ans=dp[1][0][0];
        out.println(ans);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }

/****************************************Template Begins************************************************/
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.00000000000000000");
        out.println(ft.format(d));
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            if(p1.u!=p2.u){
                return p1.u-p2.u;
            }
            else{
                return p2.v-p1.v;
            }
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }

        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }

        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }

        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }

        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long aa=p2.u-p1.u;
            if(aa<0){
                return -1;
            }
            else if(aa>0){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pair> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pair other = (Pair) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pair other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}


/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static ArrayList<Long> factorial;
    static HashSet<Pair> graph[];
/****************************************Solutions Begins***************************************/
    static int input[],freq[],n,m;
    static int dp[][][];
    static int dfs(int i,int x,int y){
        if(i==m+1){
            if(x==0&&y==0)
                return 0;
            else
                return Integer.MIN_VALUE/5;
        }
        if(dp[i][x][y]!=-1){
            return dp[i][x][y];
        }
        if(freq[i]-x-y<0){
            return Integer.MIN_VALUE/5;
        }
        int rem=freq[i]-x-y;
        int a1=Integer.MIN_VALUE;
        for(int j=0;j<=Math.min(2,rem);j++){
            a1=Math.max(a1,(rem-j)/3+j+dfs(i+1,j,x));
        }
        //debug(i,x,y,a1);
        dp[i][x][y]=a1;
        return dp[i][x][y];
    }
    public static void main (String[] args) throws Exception {
        String st[]=br.readLine().split(" ");
        n=Integer.parseInt(st[0]);
        m=Integer.parseInt(st[1]);
        st=br.readLine().split(" ");
        input=new int[n];
        freq=new int[m+1];
       // debug(freq);
        for(int i=0;i<n;i++){
            input[i]=Integer.parseInt(st[i]);
            freq[input[i]]++;
        }
        //debug(freq);
        dp=new int[m+1][3][3];
        for(int arr[][]:dp){
            for(int ar[]:arr){
                Arrays.fill(ar,-1);
            }
        }
        int ans=dfs(1,0,0);
        out.println(ans);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }

/****************************************Template Begins************************************************/
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.00000000000000000");
        out.println(ft.format(d));
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            if(p1.u!=p2.u){
                return p1.u-p2.u;
            }
            else{
                return p2.v-p1.v;
            }
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }

        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }

        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }

        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }

        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long aa=p2.u-p1.u;
            if(aa<0){
                return -1;
            }
            else if(aa>0){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pair> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pair other = (Pair) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pair other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskD {
		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			final int N = (int) 1e6 + 1;
			final int infinity = (int) 1e9;

			int[] a = new int[N];
			int n = in.nextInt();
			for (int i = 0; i < n; i++) {
				int x = in.nextInt();
				++a[x];
			}
			int[][] d = new int[N][9];
			for (int[] arr : d) {
				Arrays.fill(arr, -infinity);
			}
			d[0][0] = 0;
			for (int i = 1; i < N; i++) {
				for (int asFirst = 0; asFirst < 3; asFirst++) {
					if (i + 2 >= N && asFirst != 0) {
						continue;
					}
					for (int asSecond = 0; asSecond < 3; asSecond++) {
						if (i + 1 >= N && asSecond != 0) {
							continue;
						}
						if (i - 1 < 0 && asSecond != 0) {
							continue;
						}
						for (int asThird = 0; asThird < 3; asThird++) {
							if (i - 2 < 0 && asThird != 0) {
								continue;
							}
							int rem = a[i] - asFirst - asSecond - asThird;
							if (rem < 0) {
								continue;
							}
							d[i][3 * asFirst + asSecond] = Math.max(d[i][3 * asFirst + asSecond], d[i - 1][3 * asSecond + asThird] + asThird + rem / 3);
						}
					}
				}
			}
			out.println(d[N - 1][0]);
		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

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

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

	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskD {
		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			final int infinity = (int) 1e9;
			int n = in.nextInt();
			int m = in.nextInt();
			int[] a = new int[m + 1];
			for (int i = 0; i < n; i++) {
				int x = in.nextInt();
				++a[x];
			}
			int[][] d = new int[m + 1][9];
			for (int[] arr : d) {
				Arrays.fill(arr, -infinity);
			}
			d[0][0] = 0;
			for (int i = 1; i <= m; i++) {
				for (int asFirst = 0; asFirst < 3; asFirst++) {
					for (int asSecond = 0; asSecond < 3; asSecond++) {
						for (int asThird = 0; asThird < 3; asThird++) {
							int rem = a[i] - asFirst - asSecond - asThird;
							if (rem < 0) {
								continue;
							}
							d[i][3 * asFirst + asSecond] = Math.max(d[i][3 * asFirst + asSecond], d[i - 1][3 * asSecond + asThird] + asThird + rem / 3);
						}
					}
				}
			}
			out.println(d[m][0]);
		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

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

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

	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author prakharjain
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DJongmah solver = new DJongmah();
        solver.solve(1, in, out);
        out.close();
    }

    static class DJongmah {
        public void solve(int testNumber, InputReader in, OutputWriter out) {

            int n = in.nextInt();

            int m = in.nextInt();

            int[] a = in.nextIntArray(n);

            int[] c = new int[m + 1];

            for (int val : a) {
                c[val]++;
            }

            if (m == 1) {
                out.println(c[1] / 3);
                return;
            }

            long[][][] dp = new long[m + 1][3][5];

            for (int k = 0; k <= m; k++) {
                for (int i = 0; i <= 2; i++) {
                    for (int j = 0; j <= 4; j++) {
                        dp[k][i][j] = -1;
                    }
                }
            }

            for (int i = 0; i <= 2; i++) {
                for (int j = 0; j <= 4; j++) {
                    if (c[1] < i || c[2] < j)
                        continue;
                    int rem0 = (c[1] - i) / 3;
                    int rem1 = (c[2] - j) / 3;
                    dp[2][i][j] = Math.max(dp[2][i][j], rem0 + rem1);
                }
            }

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

                        if (dp[k - 1][i][j] == -1)
                            continue;

                        for (int l = 0; l <= 2; l++) {
                            for (int o = 0; o <= 2; o++) {

                                if (Math.min(i, j) < l)
                                    continue;

                                if (c[k] < l + o)
                                    continue;

                                int rem = c[k] - l - o;

                                int jrem = Math.min(j - l, 2);

                                int ex = 0;

                                dp[k][jrem][o] = Math.max(dp[k][jrem][o], dp[k - 1][i][j] + rem / 3 + l);
                            }
                        }
                    }
                }
            }

            long ans = 0;

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

            out.println(ans);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

        public void println(int i) {
            writer.println(i);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

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

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int 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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; ++i) array[i] = nextInt();
            return array;
        }

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

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author prakharjain
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DJongmah solver = new DJongmah();
        solver.solve(1, in, out);
        out.close();
    }

    static class DJongmah {
        public void solve(int testNumber, InputReader in, OutputWriter out) {

            int n = in.nextInt();

            int m = in.nextInt();

            int[] a = in.nextIntArray(n);

            int[] c = new int[m + 1];

            for (int val : a) {
                c[val]++;
            }

            if (m == 1) {
                out.println(c[1] / 3);
                return;
            }

            long[][][] dp = new long[m + 1][3][5];

            for (int k = 0; k <= m; k++) {
                for (int i = 0; i <= 2; i++) {
                    for (int j = 0; j <= 4; j++) {
                        dp[k][i][j] = -1;
                    }
                }
            }

            for (int i = 0; i <= 2; i++) {
                for (int j = 0; j <= 4; j++) {
                    if (c[1] < i || c[2] < j)
                        continue;
                    int rem0 = (c[1] - i) / 3;
                    int rem1 = (c[2] - j) / 3;
                    dp[2][i][j] = Math.max(dp[2][i][j], rem0 + rem1);
                }
            }

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

                        if (dp[k - 1][i][j] == -1)
                            continue;

                        for (int l = 0; l <= 2; l++) {
                            for (int o = 0; o <= 4; o++) {

                                if (Math.min(i, j) < l)
                                    continue;

                                if (c[k] < l + o)
                                    continue;

                                int rem = c[k] - l - o;

                                int jrem = Math.min(j - l, 2);

                                int ex = 0;

                                dp[k][jrem][o] = Math.max(dp[k][jrem][o], dp[k - 1][i][j] + rem / 3 + l);
                            }
                        }
                    }
                }
            }

            long ans = 0;

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

            out.println(ans);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

        public void println(int i) {
            writer.println(i);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

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

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int 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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public int[] nextIntArray(int n) {
            int[] array = new int[n];
            for (int i = 0; i < n; ++i) array[i] = nextInt();
            return array;
        }

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

        }

    }
}


//package global001;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class D {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		int[] f = new int[m+1];
		for(int i = 0;i < n;i++)f[ni()]++;
		int[][] dp = new int[6][6];
		for(int i = 0;i < 6;i++)Arrays.fill(dp[i], -9999999);
		dp[0][0] = 0;
		for(int i = 0;i <= m;i++){
			int[][] ndp = new int[6][6];
			for(int j = 0;j < 6;j++)Arrays.fill(ndp[j], -9999999);
			for(int j = 0;j < 6;j++){
				for(int k = 0;k < 6;k++){
					if(dp[j][k] < 0)continue;
					for(int l = 0;l <= j && l <= k && l <= f[i];l++){
						int u = (f[i]-l) % 3;
						ndp[k-l][u] = Math.max(ndp[k-l][u], (f[i]-l)/3 + l + dp[j][k]);
						u += 3;
						if(u <= f[i]){
							ndp[k-l][u] = Math.max(ndp[k-l][u], (f[i]-l)/3-1 + l + dp[j][k]);
						}
					}
				}
			}
			dp = ndp;
		}
		long ans = 0;
		for(int i = 0;i < 6;i++){
			for(int j = 0;j < 6;j++){
				ans = Math.max(ans, dp[i][j]);
			}
		}
		out.println(ans);
	}

	void run() throws Exception
	{
//		int n = 1000000, m = 99999;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(n + " ");
//		sb.append(m + " ");
//		for (int i = 0; i < n; i++) {
//			sb.append(gen.nextInt(m)+1 + " ");
//		}
//		INPUT = sb.toString();

		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

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

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

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

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

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

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

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

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

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

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

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

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

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

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

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}