# -*- coding: utf-8 -*-



"""

参考：https://img.atcoder.jp/abc105/editorial.pdf

　　　http://drken1215.hatenablog.com/entry/2018/08/13/125300

　　　https://www.hamayanhamayan.com/entry/2018/08/12/010816

・左端固定で右端動かすループの累積和だけ取れば、

　(右端の累積和)-(左端-1の累積和)で、どこでも分かるようになる。

・B-AがMの倍数 → BとAのmod Mが等しい(やってみれば分かる)

・余りの数を全部集計してから、各余りの数について2つ選ぶ組み合わせを数える。

"""



from collections import defaultdict



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

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



# 累積和を一時的に格納する変数

sm = 0

# 累積和のmod Mを格納するdict

d = defaultdict(int)

# 何もない累積和0の分を足しておく

d[0] = 1

for i in range(N):

    sm += + aN[i]

    d[sm%M] += 1



ans = 0

for k, v in list(d.items()):

    # 各余りの数について、v個から2つ選ぶ組み合わせ(vC2)

    ans += v * (v-1) // 2

print(ans)

# -*- coding: utf-8 -*-



import sys

from itertools import accumulate

from collections import Counter



def input(): return sys.stdin.readline().strip()

def list2d(a, b, c): return [[c] * b for i in range(a)]

def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1): return int(-(-x // y))

def INT(): return int(eval(input()))

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

def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes(): print('Yes')

def No(): print('No')

def YES(): print('YES')

def NO(): print('NO')

sys.setrecursionlimit(10 ** 9)

INF = 10 ** 18

MOD = 10 ** 9 + 7



N, M = MAP()

# Mの倍数が欲しいのでとりあえずMOD Mする

A = [a%M for a in LIST()]



# 累積和

acc = [0] + [a%M for a in accumulate(A)]

C = Counter(acc)

ans = 0

for v in list(C.values()):

    # 同値のペアが区間和が0(Mの倍数)になるので、そこを数える

    ans += v * (v-1) // 2

print(ans)

# -*- coding: utf-8 -*-
"""
参考：https://img.atcoder.jp/abc105/editorial.pdf
　　　http://drken1215.hatenablog.com/entry/2018/08/13/125300
　　　https://www.hamayanhamayan.com/entry/2018/08/12/010816
・左端固定で右端動かすループの累積和だけ取れば、
　(右端の累積和)-(左端-1の累積和)で、どこでも分かるようになる。
・B-AがMの倍数 → BとAのmod Mが等しい(やってみれば分かる)
・余りの数を全部集計してから、各余りの数について2つ選ぶ組み合わせを数える。
"""
from collections import defaultdict

N, M = list(map(int, input().split()))
aN = list(map(int, input().split()))
# 累積和を一時的に格納する変数
sm = 0
# 累積和のmod Mを格納するdict
d = defaultdict(int)
# 何もない累積和0の分を足しておく
d[0] = 1
for i in range(N):
    sm += +aN[i]
    d[sm % M] += 1
ans = 0
for k, v in list(d.items()):
    # 各余りの数について、v個から2つ選ぶ組み合わせ(vC2)
    ans += v * (v - 1) // 2
print(ans)

# -*- coding: utf-8 -*-
import sys
from itertools import accumulate
from collections import Counter


def input():
    return sys.stdin.readline().strip()


def list2d(a, b, c):
    return [[c] * b for i in range(a)]


def list3d(a, b, c, d):
    return [[[d] * c for j in range(b)] for i in range(a)]


def list4d(a, b, c, d, e):
    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]


def ceil(x, y=1):
    return int(-(-x // y))


def INT():
    return int(eval(input()))


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


def LIST(N=None):
    return list(MAP()) if N is None else [INT() for i in range(N)]


def Yes():
    print("Yes")


def No():
    print("No")


def YES():
    print("YES")


def NO():
    print("NO")


sys.setrecursionlimit(10**9)
INF = 10**18
MOD = 10**9 + 7
N, M = MAP()
# Mの倍数が欲しいのでとりあえずMOD Mする
A = [a % M for a in LIST()]
# 累積和
acc = [0] + [a % M for a in accumulate(A)]
C = Counter(acc)
ans = 0
for v in list(C.values()):
    # 同値のペアが区間和が0(Mの倍数)になるので、そこを数える
    ans += v * (v - 1) // 2
print(ans)

-""" -参考：https://img.atcoder.jp/abc105/editorial.pdf -　　　http://drken1215.hatenablog.com/entry/2018/08/13/125300 -　　　https://www.hamayanhamayan.com/entry/2018/08/12/010816 -・左端固定で右端動かすループの累積和だけ取れば、 -　(右端の累積和)-(左端-1の累積和)で、どこでも分かるようになる。 -・B-AがMの倍数 → BとAのmod Mが等しい(やってみれば分かる) -・余りの数を全部集計してから、各余りの数について2つ選ぶ組み合わせを数える。 -""" -from collections import defaultdict +import sys +from itertools import accumulate +from collections import Counter -N, M = list(map(int, input().split())) -aN = list(map(int, input().split())) -# 累積和を一時的に格納する変数 -sm = 0 -# 累積和のmod Mを格納するdict -d = defaultdict(int) -# 何もない累積和0の分を足しておく -d[0] = 1 -for i in range(N): -    sm += +aN[i] -    d[sm % M] += 1 + +def input(): +    return sys.stdin.readline().strip() + + +def list2d(a, b, c): +    return [[c] * b for i in range(a)] + + +def list3d(a, b, c, d): +    return [[[d] * c for j in range(b)] for i in range(a)] + + +def list4d(a, b, c, d, e): +    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)] + + +def ceil(x, y=1): +    return int(-(-x // y)) + + +def INT(): +    return int(eval(input())) + + +def MAP(): +    return list(map(int, input().split())) + + +def LIST(N=None): +    return list(MAP()) if N is None else [INT() for i in range(N)] + + +def Yes(): +    print("Yes") + + +def No(): +    print("No") + + +def YES(): +    print("YES") + + +def NO(): +    print("NO") + + +sys.setrecursionlimit(10**9) +INF = 10**18 +MOD = 10**9 + 7 +N, M = MAP() +# Mの倍数が欲しいのでとりあえずMOD Mする +A = [a % M for a in LIST()] +# 累積和 +acc = [0] + [a % M for a in accumulate(A)] +C = Counter(acc) -for k, v in list(d.items()): -    # 各余りの数について、v個から2つ選ぶ組み合わせ(vC2) +for v in list(C.values()): +    # 同値のペアが区間和が0(Mの倍数)になるので、そこを数える