Problem:
Score : 700 points

Problem Statement

Takahashi is playing with N cards.

The i-th card has an integer X_i on it.

Takahashi is trying to create as many pairs of cards as possible satisfying one of the following conditions:

The integers on the two cards are the same.

The sum of the integers on the two cards is a multiple of M.

Find the maximum number of pairs that can be created.

Note that a card cannot be used in more than one pair.

Constraints

2≦N≦10^5

1≦M≦10^5

1≦X_i≦10^5

Input

The input is given from Standard Input in the following format:

N M
X_1 X_2 ... X_N

Output

Print the maximum number of pairs that can be created.

Sample Input 1

7 5
3 1 4 1 5 9 2

Sample Output 1

3

Three pairs (3,2), (1,4) and (1,9) can be created.

It is possible to create pairs (3,2) and (1,1), but the number of pairs is not maximized with this.

Sample Input 2

15 10
1 5 6 10 11 11 11 20 21 25 25 26 99 99 99

Sample Output 2

6

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

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

public class Main {

	private static boolean DEBUG = false;

	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		String[] raw = reader.readLine().split("\\s");
		int N = Integer.parseInt(raw[0]);
		int M = Integer.parseInt(raw[1]);
		raw = reader.readLine().split("\\s");
		RemainderItem[] C = new RemainderItem[M/2 + 1];
		for (int j = 0; j < C.length; j++)
			C[j] = new RemainderItem();
		for (int j = 0; j < N; j++) {
			int item = Integer.parseInt(raw[j]);
			int r = item % M;
			int c = r;
			if (r < C.length) {
				C[r].P++;
			}
			else {
				C[M-r].N++;
				c = M-r;
			}
			if (!C[c].ClassItems.containsKey(item)) 
				C[c].ClassItems.put(item, 1);
			else
				C[c].ClassItems.put(item, C[c].ClassItems.get(item) + 1);
		}
		long result = 0;
		if (DEBUG) {
			System.out.println("Classes:");
			for (int j = 0; j < C.length; j++) {
				System.out.print(String.format("Class %d: P: %d N: %d (", j, C[j].P, C[j].N));
				for (int key: C[j].ClassItems.keySet())
					System.out.print(String.format("[key: %d, count: %d]", key, C[j].ClassItems.get(key)));
				System.out.println();
			}
		}
		for (int j = 0; j < C.length; j++) {
			// zero class adds all items.
			if (j == 0 || (M%2 == 0 && j == M / 2)) {
				result += (C[j].P + C[j].N) / 2;
			}
			else {
				int min = Math.min(C[j].P, C[j].N);
				int max = Math.max(C[j].P, C[j].N);
				long ep = 0;
				if (max - min > 1) {
					for (int key: C[j].ClassItems.keySet()) {
						if (C[j].ClassItems.get(key) > 0)
							ep += C[j].ClassItems.get(key) / 2;
					}
					ep = Math.min(ep, (long)(max - min) / 2);
				}
				if (DEBUG) {
					System.out.println(String.format("Class %d sums %d", j, min+ep));
				}
				result += min + ep;
			}
		}
		System.out.println(result);
	}

	static class RemainderItem {
		int P, N;
		Map<Integer, Integer> ClassItems;

		public RemainderItem() {
			ClassItems = new HashMap<Integer, Integer>();
		}
	}
	
}