#include<iostream>
#include<iomanip>
#include<math.h>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#define INF 1000000000ll
#define MOD 1000000007ll
#define EPS 1e-10
#define REP(i,m) for(long long i=0; i<m; ++i)
#define FOR(i,n,m) for(long long i=n; i<m; ++i)
#define DUMP(n,a) for(long long dump=0; dump<n; ++dump) { cout<<a[dump]; if(dump!=n-1) cout<<" "; else cout<<endl; }
#define ALL(v) v.begin(),v.end()
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef long double ld;

/*
 貪欲
 ①決定問題 必ず解に含まれる(含むように変換できる)ものから決めていく みんプロ本選B
 ②最適化問題 任意の解から評価を落とさず解に含められるようなものから決めていく 区間スケジューリングとか
 ③
 */

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll n,m;
	cin>>n>>m;
	vector<ll> x(n);
	REP(i,n) cin>>x[i];
	if(m==1) {
		cout<<n/2<<endl;
		return 0;
	}
	vector<vector<ll>> s(m);
	REP(i,n) {
		s[x[i]%m].pb(x[i]);
	}
	ll ret=0;
	ret+=(ll)s[0].size()/2;
	for(ll i=1; m-i>=i; i++) {
		if(m-i==i) {
			ret+=(ll)s[i].size()/2;
			continue;
		}
		ll sml=i,bg=m-i;
		if((ll)s[sml].size()>(ll)s[bg].size()) swap(sml,bg);
		sort(ALL(s[bg]));
		ll cnt=0,buf=0;
		FOR(j,1,(ll)s[bg].size()) {
			if(s[bg][j]==s[bg][j-1]) {
				if(buf==0) buf=2;
				else buf++;
			}
			else {
				cnt+=buf/2;
				buf=0;
			}
		}
		cnt+=buf/2;
		ret+=(ll)s[sml].size();
		ret+=min(((ll)s[bg].size()-(ll)s[sml].size())/2,cnt);
	}
	cout<<ret<<endl;
}
