CodeEff/ECCO huggingface dataset:
# Original solution
n, m = list(map(int, input().split()))
l = list(map(int, input().split()))

l = [0] + l
from itertools import accumulate
cum =list(accumulate(l))
cum = [c%m for c in cum]

d = {}
ans = 0
for i in range(n+1):
  if cum[i] not in d:
    d[cum[i]] = 1
  else:
    ans += d[cum[i]]
    d[cum[i]] += 1
print(ans)

# Optimized solution
n, m = list(map(int, input().split()))
A = list(map(int, input().split()))
from itertools import accumulate
B = [0]+A
B = list(accumulate(B))
d = {}
ans = 0
for i in range(n+1):
    s = B[i]%m
    if s in d:
        ans += d[s]
        d[s] += 1
    else:
        d[s] = 1
print(ans)
# Original solution
# -*- coding: utf-8 -*-
# import numpy as np

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

pare_list = []
val_list = []

for i in range(N):
    tmp = 0
    for j in range(i,N):
        tmp += An[j]
        pare_list.append((i,j))
        # for m in range(i,j+1):
        #     tmp += An[m]
        val_list.append(tmp)

count = 0
for val in val_list:
    if val % M == 0:
        count += 1


print(count)
# print(pare_list)
# print(val_list)


# Optimized solution
# -*- coding: utf-8 -*-
# import numpy as np

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

pare_list = []
val_list = []

for i in range(N):
    tmp = 0
    for j in range(i,N):
        tmp += An[j]
        # pare_list.append((i,j))
        # for m in range(i,j+1):
        #     tmp += An[m]
        if tmp % M == 0:
            val_list.append(tmp)

print((len(val_list)))
#
# count = 0
# for val in val_list:
#     if val % M == 0:
#         count += 1


# print(count)
# print(pare_list)
# print(val_list)
# Original solution
N, M = list(map( int, input().split()))
A = list( map( int, input().split()))
A = [ x%M for x in A]
SUM = [0]
for i in range(N):
    SUM.append(SUM[-1]+A[i])
ans = 0
cnt = 1
for l in range(N):
    if A[l] == 0:
        ans += cnt
        cnt += 1
    else:
        PART = 0
        for r in range(l+1,N+1):
            if (SUM[r] - SUM[l])%M == 0:
                PART += 1
        ans += cnt * PART
        cnt = 1
print((int(ans)))

# Optimized solution
N, M = list(map( int, input().split()))
A = list( map( int, input().split()))
D = {0:1}
a = 0
ans = 0
for i in range(N):
    a = (a+A[i])%M
    ans += D.get(a,0)
    D[a] = 1 + D.get(a,0)
print(ans)
# Original solution
import sys
import math
import collections
import itertools
import array
import inspect

# Set max recursion limit
sys.setrecursionlimit(10000)


# Debug output
def chkprint(*args):
    names = {
        id(v): k
        for k, v in list(inspect.currentframe().f_back.f_locals.items())
    }
    print((', '.join(
        names.get(id(arg), '???') + ' = ' + repr(arg) for arg in args)))


# Binary converter
def to_bin(x):
    return bin(x)[2:]


def li_input():
    return [int(_) for _ in input().split()]


# --------------------------------------------

dp = None


def main():
    N, M = li_input()
    A = li_input()

    ans = 0

    cumsum = [0]
    c_sum = 0
    for a in A:
        c_sum += a
        cumsum.append(c_sum)

    for r in range(1, len(cumsum)):
        for l in range(r):
            if (cumsum[r] - cumsum[l]) % M == 0:
                ans += 1

    print(ans)


main()


# Optimized solution
import sys
import math
import collections
import itertools
import array
import inspect

# Set max recursion limit
sys.setrecursionlimit(10000)


# Debug output
def chkprint(*args):
    names = {
        id(v): k
        for k, v in list(inspect.currentframe().f_back.f_locals.items())
    }
    print((', '.join(
        names.get(id(arg), '???') + ' = ' + repr(arg) for arg in args)))


# Binary converter
def to_bin(x):
    return bin(x)[2:]


def li_input():
    return [int(_) for _ in input().split()]


# --------------------------------------------

dp = None


def main():
    N, M = li_input()
    A = li_input()

    ans = 0
    d = collections.defaultdict(lambda: 0)

    cumsum = [0]
    c_sum = 0
    for a in A:
        c_sum = (c_sum + a) % M
        cumsum.append(c_sum)

    for c in cumsum:
        d[c] += 1

    for v in list(d.values()):
        if v >= 2:
            ans += v * (v - 1) // 2

    print(ans)


main()
# Original solution
import math
n,m = list(map(int,input().split()))
a = list(map(int,input().split()))

s = []
k = 0
for i in range(0,n):
    k += a[i]
    s.append(k)

for i in range(0,n):
    s[i] = s[i]%m

d = [0]
ass = 0
w = s.count(0)
ass += w*(w+1)//2

for i in range(0,n):
    if s[i] not in d:
        d.append(s[i])
        w = s.count(s[i])
        if w != 1:
            ass += w*(w-1)//2

print(ass)

# Optimized solution
import bisect
n,m = list(map(int,input().split()))
a = list(map(int,input().split()))

s = []
k = 0
for i in range(0,n):
    k += a[i]
    s.append(k%m)

ass = 0
w = s.count(0)
ass += w*(w+1)//2
s.sort()

hj = w
while hj <= n-1:
    jkl = bisect.bisect_right(s,s[hj])
    w = jkl - hj
    if w != 1:
        ass += w*(w-1)//2
    hj = jkl
print(ass)
# Original solution
import collections
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))

# 普通の累積和
cumsum = [0]
for i in range(N):
    cumsum.append(cumsum[-1] + A[i])

# 上で作った累積和のmodMを計算
cumsum_2 = []
for i in range(N + 1):
    cumsum_2.append(cumsum[i] % M)

c = collections.Counter(cumsum_2)

ans = 0
for v in list(c.values()):
    ans += v * (v - 1) // 2

print(ans)


# Optimized solution
import collections
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))

# 普通の累積和
cumsum = [0]
for i in range(N):
    cumsum.append(cumsum[-1] + A[i])

# 上で作った累積和のmodMを計算
cumsum_mod = []
for i in range(N + 1):
    cumsum_mod.append(cumsum[i] % M)

c = collections.Counter(cumsum_mod)

ans = 0
for v in list(c.values()):
    ans += v * (v - 1) // 2

print(ans)
# Original solution
def candy_distribution(N: int, M: int, A: list)->int:
    S = [0] * (N+1)
    for i, a in enumerate(A):
        S[i+1] = S[i] + a

    count = 0
    for l in range(1, N+1):
        for r in range(l, N+1):
            if (S[r] - S[l-1]) % M == 0:
                # print('S({}, {}) = {}'.format(l, r, S[r] - S[l-1]))
                count += 1

    return count


if __name__ == "__main__":
    N, M = list(map(int, input().split()))
    A = [int(s) for s in input().split()]
    ans = candy_distribution(N, M, A)
    print(ans)


# Optimized solution
def candy_distribution(N: int, M: int, A: list)->int:
    S = 0
    remainders = {}
    remainders[0] = 1
    for a in A:
        S = (S + a) % M
        if S not in remainders:
            remainders[S] = 0
        remainders[S] += 1

    count = sum(r*(r-1)//2 for r in list(remainders.values()))
    # for l in range(1, N+1):
    #     for r in range(l, N+1):
    #         if (S[r] - S[l-1]) % M == 0:
    #             # print('S({}, {}) = {}'.format(l, r, S[r] - S[l-1]))
    #             count += 1

    return count


if __name__ == "__main__":
    N, M = list(map(int, input().split()))
    A = [int(s) for s in input().split()]
    ans = candy_distribution(N, M, A)
    print(ans)
# Original solution
n,m=list(map(int,input().split()))
A=list(map(int,input().split()))
for i in range(n):
    A[i]=A[i]%m

B=[]

for i in range(n):
    sumi=A[i]
    ri=i+1
    while ri<n and sumi%m!=0 :
        sumi=(sumi+A[ri])%m
        ri+=1
    if ri==n and sumi%m!=0 :
        ri=-1
    B.append(ri)
#print(B)

mco=0
for i in range(n):
    coi=0
    ms=0
    s=i
    while s!=n and s!=-1 :
        ms=s
        s=B[s]
        B[ms]=-1
        coi+=1
        #print("s"+str(s))
    if s==-1 :
        coi-=1
    #print(coi)
    mco+=coi*(coi+1)//2

print(mco)


# Optimized solution
n,m=list(map(int,input().split()))
A=list(map(int,input().split()))

B=[]
su=0
for i in range(n):
    su+=A[i]
    B.append(su)

#print(B)

C={}
C[0]=1
for i in range(n):
    C[B[i]%m]=C.get(B[i]%m,0)+1

#print(C)

#D=C.values()
su=0
#print(C.values())
for i in list(C.values()):
    su+=i*(i-1)//2
print(su)
# Original solution
#list_int 並べて出力 print (' '.join(map(str,ans_li)))
#list_str 並べて出力 print (' '.join(list))

from collections import defaultdict
import sys,heapq,bisect,math,itertools,string,queue,datetime
sys.setrecursionlimit(10**8)
INF = float('inf')
mod = 10**9+7
eps = 10**-7
AtoZ = [chr(i) for i in range(65,65+26)]
atoz = [chr(i) for i in range(97,97+26)]

def inpl(): return list(map(int, input().split()))
def inpl_s(): return list(input().split())

N,M = inpl()
aa = inpl()
ans = 0

ed = [0]
SUM_L = defaultdict(int)
SUM_R = defaultdict(int)
SUM_L[0] += 1
SUM_R[0] += 1
SUM = sum(aa) % M

tmpL = tmpR = 0
for i in range(N):
	tmpL += aa[i]
	tmpL %= M
	if SUM_L[tmpL] == 0:
		ed.append(tmpL)
	SUM_L[tmpL] += 1

	tmpR += aa[N-i-1]
	tmpR %= M
	SUM_R[tmpR] += 1

ans = 0
for l in ed:
	numL = SUM_L[l]
	r = (SUM - l) % M
	numR = SUM_R[r]
	ans += numL * (numR-1)

print((ans//2))


# Optimized solution
from collections import defaultdict
import sys,heapq,bisect,math,itertools,string,queue,datetime
sys.setrecursionlimit(10**8)
INF = float('inf')
mod = 10**9+7
eps = 10**-7
AtoZ = [chr(i) for i in range(65,65+26)]
atoz = [chr(i) for i in range(97,97+26)]

def inpl(): return list(map(int, input().split()))
def inpl_s(): return list(input().split())

N,M = inpl()
aa = inpl()
ans = 0
modSUM = defaultdict(int)

tmp = 0
modSUM[0] += 1
for a in aa:
	tmp += a
	tmp %= M
	ans += modSUM[tmp]
	modSUM[tmp] += 1

print(ans)
# Original solution
# -*- coding: utf-8 -*-
import bisect
import heapq
import math
import random
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from fractions import Fraction
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations, accumulate
from operator import add, mul, sub, itemgetter, attrgetter


import sys
# sys.setrecursionlimit(10**6)
# readline = sys.stdin.buffer.readline
readline = sys.stdin.readline

INF = 2**62-1


def read_int():
    return int(readline())


def read_int_n():
    return list(map(int, readline().split()))


def read_float():
    return float(readline())


def read_float_n():
    return list(map(float, readline().split()))


def read_str():
    return readline().strip()


def read_str_n():
    return readline().strip().split()


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.perf_counter()
        ret = f(*args, **kwargs)
        e = time.perf_counter()

        error_print(e - s, 'sec')
        return ret

    return wrap


@mt
def slv(N, M, A):
    sa = [0] + list(accumulate(A))
    sam = [a % M for a in sa]
    ans = 0
    for n in Counter(sam).values():
        ans += n*(n-1)//2
    return ans

def main():
    N, M = read_int_n()
    A = read_int_n()
    print(slv(N, M, A))


if __name__ == '__main__':
    main()


# Optimized solution
# -*- coding: utf-8 -*-
import bisect
import heapq
import math
import random
from collections import Counter, defaultdict, deque
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from fractions import Fraction
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations, accumulate
from operator import add, mul, sub, itemgetter, attrgetter


import sys
# sys.setrecursionlimit(10**6)
# readline = sys.stdin.buffer.readline
readline = sys.stdin.readline

INF = 2**62-1


def read_int():
    return int(readline())


def read_int_n():
    return list(map(int, readline().split()))


def read_float():
    return float(readline())


def read_float_n():
    return list(map(float, readline().split()))


def read_str():
    return readline().strip()


def read_str_n():
    return readline().strip().split()


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.perf_counter()
        ret = f(*args, **kwargs)
        e = time.perf_counter()

        error_print(e - s, 'sec')
        return ret

    return wrap


@mt
def slv(N, M, A):
    return reduce(lambda x, y: x + y*(y-1)//2, Counter(accumulate([0]+A, lambda x, y: (x+y) % M)).values(), 0)


def main():
    N, M = read_int_n()
    A = read_int_n()
    print(slv(N, M, A))


if __name__ == '__main__':
    main()
# Original solution
n, m = list(map(int, input().split()))
aa = [int(ak) % m for ak in input().split()]
mod = {}
ans = 0
zi = 0
for a in aa:
    zi = (zi - a) % m
    ai = (zi + a) % m
    mod.setdefault(ai,0)
    mod[ai] += 1
    ans += mod.get(zi,0)
print(ans)


# Optimized solution
def f(n, m):
    aa = [int(ak) % m for ak in input().split()]
    mod = {}
    ans = 0
    zi = 0
    for a in aa:
        zi = (zi - a) % m
        ai = (zi + a) % m
        mod.setdefault(ai, 0)
        mod[ai] += 1
        ans += mod.get(zi, 0)
    print(ans)


n, m = list(map(int, input().split()))
f(n, m)
# Original solution
def f(n, m):
    aa = [int(ak) % m for ak in input().split()]
    mod = {}
    ans = 0
    zi = 0
    for a in aa:
        zi = (zi - a) % m
        ai = (zi + a) % m
        mod.setdefault(ai, 0)
        mod[ai] += 1
        ans += mod.get(zi, 0)
    print(ans)


n, m = list(map(int, input().split()))
f(n, m)


# Optimized solution
def f(m):
    aa = [int(ak) % m for ak in input().split()]
    mod = {}
    ans = 0
    zi = 0
    for a in aa:
        mod.setdefault(zi, 0)
        mod[zi] += 1
        zi = (zi - a) % m
        ans += mod.get(zi, 0)
    print(ans)


_, m = list(map(int, input().split()))
f(m)
# Original solution
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))
B = [0] + [sum(A[:i+1]) % M for i in range(N)]
B.sort()
ans = 0
k = 1
C = []
for i in range(N):
    if B[i] == B[i + 1]:
        k += 1
    else:
        C.append(k)
        k = 1
C.append(k)
for k in C:
    if k > 1:
        ans += k * (k - 1) // 2
print(ans)

# Optimized solution
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))
B = [0]
b = 0
for i in range(N):
    b += A[i]
    B.append(b % M)
B.sort()
ans = 0
k = 1
C = []
for i in range(N):
    if B[i] == B[i + 1]:
        k += 1
    else:
        C.append(k)
        k = 1
C.append(k)
for k in C:
    if k > 1:
        ans += k * (k - 1) // 2
print(ans)
# Original solution
def inpl(): return [int(i) for i in input().split()]

def solve(n,S):
    Ctr = set([])
    for i in range(n+1):
        Ctr = Ctr | set([S[i]])
    Ans = {}
    for i in range(n+1):
        Ans[S[i]] = 0
    for i in range(n+1):
        Ans[S[i]] += 1
    
    ans = 0
    for i in Ctr:
        ans += Ans[i] * (Ans[i] - 1) // 2
    return(ans)

N,M = inpl()
H = inpl()

SumH = [0]
for i in range(N):
    SumH.append((SumH[-1] + H[i]) % M)

print((solve(N,SumH)))

# Optimized solution
def inpl(): return [int(i) for i in input().split()]

N,M = inpl()
H = {0: 1}
k = 0
ans = 0
for i in inpl():
    k += i
    t = k % M
    if t not in H:
        H[t] = 0
    H[t] += 1
    
for i in list(H.values()):
   ans += i * (i - 1) // 2

print(ans)
# Original solution
class Combination:
    def __init__(self, size):
        self.size = size + 2
        self.fact = [1, 1] + [0] * size

        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i

    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] // self.fact[r] // self.fact[n - r]


from collections import defaultdict

N, M = list(map(int, input().split()))
A = list(map(int, input().split()))
A = [a % M for a in A]

accA = [0] * (N + 1)
for i, a in enumerate(A, start=1):
    accA[i] = accA[i - 1] + a

cnt = defaultdict(int)
for a in accA:
    cnt[a % M] += 1

comb = Combination(N + 100)
ans = 0
for c in list(cnt.values()):
    ans += comb.ncr(c, 2)

print(ans)

# Optimized solution
from collections import defaultdict

N, M = list(map(int, input().split()))
A = list(map(int, input().split()))
A = [a % M for a in A]

accA = [0] * (N + 1)
for i, a in enumerate(A, start=1):
    accA[i] = accA[i - 1] + a

cnt = defaultdict(int)
for a in accA:
    cnt[a % M] += 1

def ncr(n, r):
    if n < 0 or r < 0 or n < r:
        return 0
    ret = 1
    for i in range(n, n - r, -1):
        ret *= i
    for i in range(1, r + 1):
        ret //= i
    return ret

ans = 0
for c in list(cnt.values()):
    ans += ncr(c, 2)

print(ans)
# Original solution
from collections import defaultdict

N, M = list(map(int, input().split()))
A = [int(x) for x in input().split()]

B = [0] * N
B[0] = A[0]
for i in range(1, N):
    B[i] = B[i - 1] + A[i]
B = [0] + B

c = defaultdict(int)
for i in range(N + 1):
    c[B[i] % M] += 1

ans = 0
for k, v in list(c.items()):
    if v >= 2:
        ans += v * (v - 1) // 2
print(ans)

# Optimized solution
from collections import Counter
from itertools import accumulate

N, M = list(map(int, input().split()))
A = [int(x) for x in input().split()]

c = Counter([0] + [x % M for x in accumulate(A)])
ans = 0
for k, v in list(c.items()):
    if v >= 2:
        ans += v * (v - 1) // 2
print(ans)
# Original solution
n, m = list(map(int, input().split()))
a = list(map(int, input().split()))
acs = [0] * (n + 1)

for i in range(1, n + 1):
    acs[i] = (acs[i - 1] + a[i - 1]) % m
cnt = 0
for l in range(n):
    for r in range(l, n):
        if acs[r] == acs[l - 1]:
            cnt += 1
print(cnt)

# Optimized solution
n, m = list(map(int, input().split()))
a = list(map(int, input().split()))
table = {0: 0}
buf = 0
cnt = 0
for i in range(n):
    buf = (buf + a[i]) % m
    if buf in table:
        cnt += table[buf]
        table[buf] += 1
    else:
        table[buf] = 1
print((cnt + table[0]))
# Original solution
import sys
from collections import defaultdict

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, m = list(map(int, input().split()))
    A = list(map(int, input().split()))

    A_sum = [0]
    for a in A:
        A_sum.append((A_sum[-1] + a) % m)

    D = defaultdict(int)
    res = 0
    for i in range(n + 1):
        res += D.get(A_sum[i], 0)
        D[A_sum[i]] += 1
    print(res)


if __name__ == '__main__':
    resolve()


# Optimized solution
import sys
from collections import defaultdict

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, m = list(map(int, input().split()))
    A = list(map(int, input().split()))

    A_sum = [0]
    D = defaultdict(int)
    D[A_sum[-1]] += 1
    for a in A:
        A_sum.append((A_sum[-1] + a) % m)
        D[A_sum[-1]] += 1

    res = 0
    for v in list(D.values()):
        res += v * (v - 1) // 2
    print(res)


if __name__ == '__main__':
    resolve()
# Original solution
N,M = list(map(int,input().split()))
A = list(map(int,input().split()))

R = [A[0]%M]


for i in range(1,N):
  R.append((R[-1]+A[i])%M)



import collections
c = collections.Counter(R)


ans = 0
for key in c:
  if key == 0:
    ans += (c[key]*(c[key]+1))/2
  else:
    ans += (c[key]*(c[key]-1))/2
  



print((int(ans)))


# Optimized solution
N,M = list(map(int,input().split()))
A = list(map(int,input().split()))

R = [A[0]%M]


for i in range(1,N):
  R.append((R[-1]+A[i])%M)

k = set(R)
dic = {i:0 for i in k}
for item in R:
  dic[item]+=1
  
  
ans = 0
if 0 in dic:
  ans = (dic[0]*(dic[0]+1))/2


for i in k:
  if i !=0 :
    ans += (dic[i]*(dic[i]-1))/2
    

    
print((int(ans)))
# Original solution
from math import factorial
from math import sqrt
from math import ceil
from itertools import permutations
from heapq import *
from collections import defaultdict
from copy import deepcopy
from math import log

N,M=list(map(int,input().split()))
def nCr(n,r):
    a=factorial(n)
    b=factorial(n-r)
    c=factorial(r)
    return int(a//(b*c))
A=[int(i)%M for i in input().split()]
L=[0]
dic=defaultdict(int)
dic[0]+=1
for i in range(N):
    a=(L[-1]+A[i])%M
    L.append(a)
    dic[a]+=1
sum=0
for i in list(dic.keys()):
    if dic[i]>=2:
        sum+=nCr(dic[i],2)
print(sum)


# Optimized solution
from collections import defaultdict

N,M=list(map(int,input().split()))
A=list(map(int,input().split()))
B=[0]*(N+1)
C=defaultdict(int)
C[0]+=1
for i in range(N):
    B[i+1]=(B[i]+A[i])%M
    C[B[i+1]]+=1
ans=0
for i in list(C.values()):
    ans+=i*(i-1)//2
print(ans)
# Original solution
n, m = [int(_) for _ in input().split()]
a = [int(_) for _ in input().split()]

t = 0
s = [0 for _ in range(n+1)]
for i in range(n):
    s[i+1] = (a[i] + t) % m
    t += a[i] % m

counter = 0
for i in range(0, n+1):
    for j in range(i+1, n+1):
        if s[i] == s[j]:
            counter += 1
print(counter)

# Optimized solution
def main():
    n, m = [int(_) for _ in input().split()]
    A = [int(_) for _ in input().split()]

    ans = 0
    d = {}

    cumsum = [0]
    c_sum = 0
    for a in A:
        c_sum = (c_sum + a) % m
        cumsum.append(c_sum)

    for c in cumsum:
        if c not in list(d.keys()):
            d[c] = 0
        d[c] += 1

    for v in list(d.values()):
        if v >= 2:
            ans += v * (v - 1) // 2

    print(ans)


main()
# Original solution
f = lambda: list(map(int,input().split()))
def s(l,m):
    ans = 0
    for i in range(len(l)):
        ans += l[i]
        ans %= m
    return ans

n,m = f()
a = f()
a = [s(a[:i],m) for i in range(n+1)]
ans = 0
from collections import Counter
for v in list(Counter(a).values()):
    ans += v*(v-1)//2
print(ans)

# Optimized solution
f = lambda: list(map(int,input().split()))

n,m = f()
a = f()
b = [0]
for i in range(n):
    b.append((b[-1]+a[i])%m)

ans = 0
from collections import Counter
for v in list(Counter(b).values()):
    ans += v*(v-1)//2
print(ans)
# Original solution
from itertools import accumulate
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))

B = [0] + A
B = list(accumulate(B))

ans = []
cnt = 0
for i in range(1, len(B)):
    for j in range(i):
        if (B[i] - B[j])%M == 0:
            cnt += 1
print(cnt)

# Optimized solution
from itertools import accumulate
N, M = list(map(int, input().split()))
A = list(map(int, input().split()))

B = [0] + A
C = {}
B = list(accumulate(B))
for i in range(1, len(B)):
    if B[i]%M not in C:
        C[B[i]%M] = 1
    else:
        C[B[i]%M] += 1
ans = 0
for i in list(C.values()):
    ans += i*(i-1)//2
if 0 in C:
    ans += C[0]
print(ans)
# Original solution
n, m = list(map(int, input().split()))
a = list(map(int, input().split()))

s = [0]#s[i]はaからi個取った累積和
for i in range(len(a)):
    s.append((s[i] + a[i]) % m)

ans = 0
d = dict()
for i in range(len(s)):
    t = d.get(s[i], 0)
    ans += t
    d[s[i]] = t + 1
print(ans)

# Optimized solution
def iin(): return int(eval(input()))
def nl(): return list(map(int, input().split()))

n, m = nl()
a = nl()

csum = [0]
for x in a:
    csum.append((csum[-1] + x) % m)

d = dict()
ans = 0
for x in csum:
    t = d.get(x, 0)
    ans += t
    d[x] = t + 1
    
print(ans)
# Original solution
from collections import defaultdict

N, M = list(map(int, input().split()))
a = tuple(map(int, input().split()))

ans = 0
d = defaultdict(int)
d[0] = 1

t = 0
for aa in a:
    t += aa
    ans += d[t % M]
    d[t % M] += 1
print(ans)


# Optimized solution
def main():
    N, M = list(map(int, input().split()))
    *A, = list(map(int, input().split()))

    d = {0: 1}

    ans = 0

    t = 0
    for x in A:
        t = (t + x) % M
        ans += (cnt := d.get(t, 0))
        d[t] = cnt + 1
    print(ans)


if __name__ == '__main__':
    main()