// Slower C++ solution:
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key



typedef long long ll;

typedef pair<ll,ll> ii;

typedef vector<int> vi;

typedef long double ld; 

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;



int n,m;

map<int,int> cnt[100001];

vi vec[100001];



int main()

{

	ios_base::sync_with_stdio(0); cin.tie(0);

	cin>>n>>m;

	for(int i=0;i<n;i++)

	{

		int x; cin >> x;

		cnt[x%m][x]++;

	}

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

	{

		for(mit it = cnt[i].begin(); it != cnt[i].end(); it++)

		{

			vec[i].pb(it->se);

		}

	}

	int ans = 0;

	for(int i = 0; 2*i <= m; i++)

	{

		if(i==0||i==m-i)

		{

			int sum=0;

			for(int j = 0; j < vec[i].size(); j++)

			{

				sum+=vec[i][j];

			}

			ans+=sum/2;

		}

		else

		{

			int clr1 = 0;

			int clr2 = 0;

			int sum1 = 0;

			int sum2 = 0;

			for(int j = 0; j < vec[i].size(); j++)

			{

				sum1 += vec[i][j];

				clr1 += (vec[i][j]/2);

			}

			for(int j = 0; j < vec[m-i].size(); j++)

			{

				sum2 += vec[m-i][j];

				clr2 += (vec[m-i][j]/2);

			}

			if(sum1>=sum2)

			{

				int mindel = min(clr1, (sum1-sum2)/2);

				sum1 -= 2*mindel;

				ans += min(sum1,sum2) + mindel;

			}

			else

			{

				int mindel = min(clr2, (sum2-sum1)/2);

				sum2 -= 2*mindel;

				ans += min(sum1,sum2) + mindel;

			}

		}

	}

	cout<<ans<<'\n';

}


// Faster C++ solution for the same problem (measured speedup: 3.555738356792263x):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key



typedef long long ll;

typedef pair <int, int> pii;

typedef pair <ll, ll> pll;

typedef pair <ll, int> pli;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef long double ld;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;



long long INF=numeric_limits<long long>::max();



int main()

{

    ios_base::sync_with_stdio(0); cin.tie(0);

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

    ll n,m,ans(0);

    cin >> n >> m;

    ll mod[m],same[100001],smod[m];

    memset(mod,0,sizeof(mod));

    memset(smod,0,sizeof(smod));

    memset(same,0,sizeof(same));

    vector< ll > x(n);

    for(ll i = 0; i < n; i++)

    {

        cin >> x[i];

        same[x[i]]++;

    }

    for(ll i = 1; i <= 100000; i++)

    {

        ll a = i%m;

        mod[a]+=same[i];

        smod[a]+=same[i]/2;

    }

    ans += mod[0]/2;

    if(m%2==0)ans += mod[m/2]/2;

    for(ll i = 1; i < (m+1)/2; i++)

    {

        ll j = m-i;

        //cout << mod[i] << " " << mod[j] << endl;

        if(mod[i]==mod[j])

        {

            ans += mod[i];

        }

        else if(mod[i]>mod[j])

        {

            ans += mod[j];

            ll left = mod[i] - mod[j];

            //cout << left/2 << " " << smod[i] << endl;

            left = min(left/2,smod[i]);

            ans += left;

        }

        else

        {

            ans += mod[i];

            ll left = mod[j] - mod[i];

            left = min(left/2,smod[j]);

            ans += left;

        }

    }

    cout << ans << endl;

}