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 (Python):
from collections import Counter
n, m = [int(item) for item in input().split()]
x = [int(item) for item in input().split()]

modm = [[] for _ in range(m)]
ans = 0
for item in x:
    modm[item % m].append(item)
for i in range(m//2+1):
    if i == 0:
        ans += len(modm[i]) // 2
    elif m % 2 == 0 and i == m // 2:
        ans += len(modm[i]) // 2
    else:
        a = modm[i]
        b = modm[m - i]
        if len(b) < len(a):
            a, b = b[:], a[:]
        ans += len(a)
        cnt = Counter(b)
        val = 0
        for key in cnt.keys():
            val += cnt[key] // 2
        ans += min(val, (len(b) - len(a)) // 2)
print(ans)

Solution (Python):
from collections import Counter
n,m=map(int,input().split())
x=[int(i) for i in input().split()]
v=[[] for i in range(m)]
for i in x:v[i%m].append(i)
a=0
for i in range(1,m//2+m%2):
  x,y=v[i],v[m-i]
  d=len(x)-len(y)
  if d<0:d,x,y=-d,y,x
  c=sorted([p[1] for p in Counter(x).items()])
  p=0
  for t in c:p+=t//2
  a+=len(y)+min(p,d//2)
a+=len(v[0])//2+(1-m%2)*len(v[m//2])//2
print(a)

Solution (Python):
from collections import Counter
n,m=map(int,input().split())
x=[int(i) for i in input().split()]
v=[[] for i in range(m)]
for i in x:v[i%m].append(i)
a=0
for i in range(1,m//2+m%2):
  x,y=v[i],v[m-i]
  d=len(x)-len(y)
  if d<0:
    d=-d
    x,y=y,x
  c=sorted([p[1] for p in Counter(x).items()])
  p=0
  for t in c:
    p+=(t//2)
  a+=len(y)+min(p,(d//2))
a+=len(v[0])//2+(len(v[m//2])//2 if m%2==0 else 0)
print(a)

Solution (Python):
from collections import Counter
n,m=map(int,input().split())
x=[int(i) for i in input().split()]
v=[[] for i in range(m)]
for i in x:v[i%m].append(i)
a=0
for i in range(1,m//2+1*(m%2==1)):
  x,y=v[i],v[m-i]
  d=len(x)-len(y)
  if d<0:
    d=-d
    x,y=y,x
  c=sorted(Counter(x).items(),key=lambda x:x[1])
  p=0
  for t in c:
    p+=(t[1]//2)
  a+=len(y)+min(p,(d//2))
a+=len(v[0])//2+(len(v[m//2])//2 if m%2==0 else 0)
print(a)

Solution (Python):
from collections import Counter
n,m=map(int,input().split())
x=[int(i) for i in input().split()]
v=[[] for i in range(m)]
for i in x:v[i%m].append(i)
a=0
for i in range(1,m//2+1*(m%2==1)):
  d=len(v[i])-len(v[m-i])
  if d<0:
    d=-d
    v[i],v[m-i]=v[m-i],v[i]
  c=sorted(Counter(v[i]).items(),key=lambda x:x[1])
  p=0
  for t in c:
    p+=(t[1]//2)
  a+=len(v[m-i])+min(p,(d//2))
a+=len(v[0])//2+(len(v[m//2])//2 if m%2==0 else 0)
print(a)

Solution (Python):
from collections import Counter
n,m=map(int,input().split())
x=[int(i) for i in input().split()]
v=[[] for i in range(m)]
for i in x:
    v[i%m].append(i)
ans=0
for i in range(1,m//2+1*(m%2==1)):
    d=len(v[i])-len(v[m-i])
    if d<0:
        d=-d
        v[i],v[m-i]=v[m-i],v[i]
    c=sorted(Counter(v[i]).items(),key=lambda x:x[1])
    p=0
    for t in c:
        p+=(t[1]//2)
    ans+=len(v[m-i])+min(p,(d//2))

ans+=len(v[0])//2+(len(v[m//2])//2 if m%2==0 else 0)
print(ans)

Solution (Python):
from collections import defaultdict, Counter


N, M = map(int, input().split())
x = list(map(int, input().split()))
x.sort()
c = Counter(x)
a = defaultdict(int)
E = defaultdict(int)
for i,j in c.items():
    a[i%M] += j
    E[i%M] += j//2
ans = a[0]//2
for i in range(1, M):
    j = M - i
    if i < j:
        m = min(a[i], a[j])
        t = min((a[i] - m)//2, E[i]) + min((a[j] - m)//2, E[j])
        ans += m+t
    elif i == j: 
        ans += a[i] //2

print(ans)

Solution (Python):
n, m = map(int, input().split())
xlist = list(sorted(map(int, input().split())))
xd = {}

modl = [0 for _ in range(m)]
for x in xlist:
  modl[x%m] += 1
  if x in xd:
    xd[x] += 1
  else:
    xd[x] = 1

mina = modl[0] // 2
ans = mina
modl[0] -= mina*2
for i in range(1, m//2+1):
  if i != m-i:
    mina = min(modl[i], modl[m-i])
    ans += mina
    modl[i] -= mina
    modl[m-i] -= mina
  else:
    mina = modl[i] // 2
    ans += mina
    modl[i] -= mina*2

for k, v in xd.items():
  tmp = min(v//2, modl[k%m]//2)
  ans += tmp
  modl[k%m] -= tmp * 2

print(ans)

Solution (Python):
from collections import defaultdict, Counter
def inpl(): return list(map(int, input().split()))

N, M = inpl()
X = sorted(inpl())
C = Counter(X)
D = defaultdict(int)
E = defaultdict(int)
for k, v in C.items():
    D[k%M] += v
    E[k%M] += v//2

ans = D[0] // 2

for i in range(1, M):
    j = M - i
    if i < j:
        x = min(D[i], D[j])
        y = min((D[i] - x)//2, E[i]) + min((D[j] - x)//2, E[j])
        ans += x + y
    elif i == j:
        ans += D[i] //2
    else:
        break

print(ans)

Solution (Python):
from collections import defaultdict, Counter
def inpl(): return list(map(int, input().split()))

N, M = inpl()
X = sorted(inpl())
C = Counter(X)
D = defaultdict(int)
E = defaultdict(int)
for k, v in C.items():
    D[k%M] += v
    E[k%M] += v//2

ans = D[0] // 2

for i in range(1, M):
    j = M - i
    if i < j:
        x = min(D[i], D[j])
        y = min((D[i] - x)//2, E[i]) + min((D[j] - x)//2, E[j])
        ans += x + y
    elif i == j:
        ans += D[i] //2
    else:
        break

print(ans)

Solution (Python):
N,m=map(int,input().split())

X=list(map(int,input().split()))



M=[[]for i in range(m)]
for i in range(len(X)):
    M[X[i]%m].append(X[i])
    


ans=len(M[0])//2
if m%2==0:
    ans+=len(M[m//2])//2

for i in range(1,(m//2)+1):
    if m%2==0:
        if i==(m//2):
            break
    ans+=min(len(M[i]),len(M[m-i]))
    
    L=[0]
    cnt=1
    if len(M[i])>len(M[m-i]):
        A=M[i]
    else:
        A=M[m-i]
    A.sort()
    for j in range(1,max(len(M[i]),len(M[m-i]))):
        if A[j]==A[j-1]:
            cnt+=1
        else:
            L.append(cnt//2)
            cnt=1
    L.append(cnt//2)
    
    if (abs(len(M[i])-len(M[m-i]))//2)<=sum(L):
        ans+=(abs(len(M[i])-len(M[m-i]))//2)
    else:
        ans+=sum(L)
    
print(ans)

Solution (Python):
MIS = lambda: map(int,input().split())

def match(L, R):
    
    
    L.sort(); R.sort()
    match = 0
    lself = rself = 0
    lrem = rrem = 0
    while L:
        if len(L) >= 2 and L[-1] == L[-2]:
            lself+= 1; match+= 1
            L.pop(); L.pop()
        else: lrem+= 1; L.pop()
    while R:
        if len(R) >= 2 and R[-1] == R[-2]:
            rself+= 1; match+= 1
            R.pop(); R.pop()
        else: rrem+= 1; R.pop()
    while lrem and rrem:
        lrem-= 1; rrem-= 1
        match+= 1
    while lrem >= 2 and rself:
        lrem-= 2; rself-= 1
        match+= 1
    while rrem >= 2 and lself:
        rrem-= 2; lself-= 1
        match+= 1
    
    return match

n, m = MIS()
card = [[] for i in range(m)]
for x in MIS(): card[x%m].append(x//m)

tot = len(card[0])//2
for i in range(1, (m+1)//2):
    tot+= match(card[i], card[m-i])
if m%2 == 0: tot+= len(card[m//2])//2
print(tot)

Solution (Python):
from collections import Counter

N,M=map(int,input().split())


X=list(map(int,input().split()))
Xremainder=[x % M for x in X]

Xcount=Counter(X)
Xremaindercount=Counter(Xremainder)





answer=Xremaindercount[0]//2
Xremaindercount[0]-=(Xremaindercount[0]//2)*2


if M%2==0:
  
  limit=int(M//2)
  answer+=Xremaindercount[M//2]//2
  Xremaindercount[M//2]-=(Xremaindercount[M//2]//2)*2
else:
  limit=int(M//2+1)

for i in range(1,limit):
  
  s=Xremaindercount[i]
  t=Xremaindercount[M-i]
  answer+=min(s,t)
  Xremaindercount[i]-=min(s,t)
  Xremaindercount[M-i]-=min(s,t)





for i in Xcount:
  
  if Xremaindercount[i%M]>=2 and Xcount[i]>=2:
    answer+=min(Xremaindercount[i%M],Xcount[i])//2
    Xremaindercount[i%M]-=(min(Xremaindercount[i%M],Xcount[i])//2)*2

print(answer)

Solution (Python):
if __name__== "__main__":
    n,m = map(int,input().split(" "))
    x = list(map(int,input().split(" ")))
    x_mod = list(map(lambda x: x%m, x))
    s = [set() for _ in range(m)]
    num = [0 for _ in range(m)]
    pair = [0 for _ in range(m)]
    dic = dict()
    sum = 0
    sum_h = 0
    for i in range(n):
        s[x_mod[i]].add(x[i])
        num[x_mod[i]] += 1
        if str(x[i]) in dic.keys():
            dic[str(x[i])] += 1
        else:
            dic[str(x[i])] = 1
        if x_mod[i]==0:
            sum += 0.5
        if m%2==0 and x_mod[i] == m/2:
            sum_h += 0.5
    for i in range(1,m):
        if i == m/2:
            continue
        p = list(s[i])
        for j in range(len(s[i])):
            pair[i] += int(dic[str(p[j])]/2)
    
    sum = int(sum)
    sum_h = int(sum_h)
    sum += sum_h
    for i in range(1,int((m+1)/2)):
        i_1 = i
        i_2 = m-i
        if num[i]>num[m-i]:
            i_1 = m-i
            i_2 = i
        sum += num[i_1]
        sum += min(int((num[i_2]-num[i_1])/2), pair[i_2])
    print(int(sum))

Solution (Python):
if __name__== "__main__":
    n,m = map(int,input().split(" "))
    x = list(map(int,input().split(" ")))
    x_mod = list(map(lambda x: x%m, x))
    s = [set() for _ in range(m)]
    num = [0 for _ in range(m)]
    pair = [0 for _ in range(m)]
    dic = [0 for _ in range(100001)]
    sum = 0
    sum_h = 0
    for i in range(n):
        s[x_mod[i]].add(x[i])
        num[x_mod[i]] += 1
        dic[x[i]] += 1
        if x_mod[i]==0:
            sum += 0.5
        if m%2==0 and x_mod[i] == m/2:
            sum_h += 0.5
    for i in range(1,m):
        if i == m/2:
            continue
        p = list(s[i])
        for j in range(len(s[i])):
            pair[i] += int(dic[p[j]]/2)
    
    sum = int(sum)
    sum_h = int(sum_h)
    sum += sum_h
    for i in range(1,int((m+1)/2)):
        i_1 = i
        i_2 = m-i
        if num[i]>num[m-i]:
            i_1 = m-i
            i_2 = i
        sum += num[i_1]
        sum += min(int((num[i_2]-num[i_1])/2), pair[i_2])
    print(int(sum))

Solution (Python):
MAX_X = 10 ** 5 + 100

def main():
    N, M = [int(i) for i in input().split()]
    X = [0] * (MAX_X + 1)
    for i in map(int, input().split()):
        X[i] += 1
    Y = [sum(X[i::M]) for i in range(min(M, MAX_X))]
    
    ans = Y[0] // 2
    Y[0] = 0
    
    try:
        if M % 2 == 0:
            ans += Y[M//2] // 2
            Y[M//2] = 0    
        for i in range(1, M//2+1):
            j = M - i
            tmp = min(Y[i], Y[j])
            ans += tmp
            Y[i] -= tmp
            Y[j] -= tmp
    except IndexError:
        print(-1)
    for i, n in enumerate(X):
        j = i % M
        if Y[j] < 2 or n < 2:
            continue
        tmp = min(Y[j]-Y[j]%2, n-n%2)
        ans += tmp // 2
        Y[j] -= tmp
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
MAX_X = 10 ** 5 + 100

def main():
    N, M = [int(i) for i in input().split()]
    X = [0] * (MAX_X + 1)
    for i in map(int, input().split()):
        X[i] += 1
    Y = [sum(X[i::M]) for i in range(min(M, MAX_X))]
    
    ans = Y[0] // 2
    Y[0] = 0
    
    if M % 2 == 0:
        ans += Y[M//2] // 2
        Y[M//2] = 0    
    for i in range(1, M//2+1):
        j = M - i
        tmp = min(Y[i], Y[j])
        ans += tmp
        Y[i] -= tmp
        Y[j] -= tmp
    try:
        for i, n in enumerate(X):
            j = i % M
            if Y[j] < 2 or n < 2:
                continue
            tmp = min(Y[j]-Y[j]%2, n-n%2)
            ans += tmp // 2
            Y[j] -= tmp
    except IndexError:
        print(-1)
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):



from collections import Counter
N, M = map(int, input().split())
X = list(map(int, input().split()))
XX = [x % M for x in X]

cc = Counter(X)
c = Counter(XX)
cnt = c[0] // 2
c[0] -= cnt * 2
if M % 2 == 1:
    to = M // 2 + 1
else:
    to = M // 2
    tmp = c[M//2] // 2
    c[M//2] -= tmp * 2
    cnt += tmp

for i in range(1, to):
    
    tmp = min(c[i], c[M-i])
    cnt += tmp
    c[i] -= tmp
    c[M-i] -= tmp



for i in cc:
    
    if cc[i] >= 2:
        
        tmp = min(c[i % M], cc[i]) // 2
        cnt += tmp
        c[i % M] -= tmp * 2
        
        




print(cnt)

Solution (Python):
from sys import exit, setrecursionlimit
from functools import reduce
from itertools import *
from collections import defaultdict
from bisect import bisect

def read():
  return int(input())

def reads():
  return [int(x) for x in input().split()]

setrecursionlimit(1000000)

(N, M) = reads()




appears = [0] * (10**5 + 1)

card = [0] * M
pair = [0] * M

for x in reads():
  if appears[x]:
    pair[x%M] += 1
  appears[x] ^= True
  card[x%M] += 1

result = 0

result += card[0] // 2

if M % 2 == 0:
  result += card[M//2] // 2





for i in range(1, (M-1)//2+1):
  use = min(card[i], card[M-i])
  card[i] -= use; card[M-i] -= use
  result += use
  
  
  
  
  
  for j in (i, M-i):
    if card[j] > 0:
      result += min(card[j] // 2, pair[j])

print(result)

Solution (Python):
n, m = map(int, raw_input().split())
X = map(int, raw_input().split())
X.sort()
P = [[] for i in xrange(m)]
S = {}
T = [0]*m
for e in X:
    P[e%m].append(e)
    S[e] = S.get(e, 0) + 1
for e in S:
    T[e%m] += S[e]/2
ans = 0
for i in xrange(1, (m-1)/2+1):
    r = min(len(P[i]), len(P[m-i]))
    ans += r
    rest = len(P[i]) - r
    ans += min(T[i], rest/2)
    rest = len(P[m-i]) - r
    ans += min(T[m-i], rest/2)
if m%2 == 0:
    ans += len(P[m/2])/2
ans += len(P[0])/2
print ans

Solution (Python):

import math
import sys

N, M = map(int, input().split())
mods = [[] for _ in range(M)]
for x in map(int, input().split()):
    mods[x % M].append(x)

mods_cnt = [len(mods[i]) for i in range(M)]

cnt = mods_cnt[0] // 2
mods_cnt[0] -= cnt * 2
if M % 2 == 0:
    c = mods_cnt[M//2] // 2
    cnt += c
    mods_cnt[M//2] -= c * 2

for i in range(1, math.ceil(M / 2)):
    c = min(mods_cnt[i], mods_cnt[-i])
    cnt += c
    mods_cnt[i] -= c
    mods_cnt[-i] -= c

for i in range(M):
    if mods_cnt[i] >= 2:
        mods_cnt[i] -= 1
        mods[i].sort()
        j = 0
        c = 0
        while j < len(mods[i]) - 1:
            if mods[i][j] == mods[i][j + 1]:
                c += 1
                j += 2
                if c * 2 >= mods_cnt[i]:
                    break
            else:
                j += 1
        cnt += c

print(cnt)