using System;
using System.Collections.Generic;
using System.Linq;

namespace CandyDistribution
{
    /// <summary>
    /// 
    /// </summary>
    public class Program2
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            // 標準入力を受け取る
            var n_m = Console.ReadLine().Split(' ');
            var n = long.Parse(n_m[0]);
            var m = long.Parse(n_m[1]);
            var boxes = Console.ReadLine().Split(' ').Select(s => long.Parse(s));

            /* N箱の内連続したi箱に入っている、お菓子の合計がMの倍数であることを確認するには、
             * とある箱までの合計お菓子数のMの剰余が、2回以上(剰余0は1回)発生した場合、
             * 前回まで割り切れた回数 +1回、割り切れる組み合わせが存在することになる。
             * ※剰余0は初回も割り切れる回数としてカウントする。
             * 例：
             * お菓子6箱(4, 1, 5, 4, 1, 5) 子供2人の場合
             * 
             * お菓子の箱番：  1,  2,  3,  4,  5,  6
             * お菓子の入数：  4,  1,  5,  4,  1,  5
             * お菓子の合計：  4,  5,  10, 14, 15, 20
             * お菓子の剰余：  0,  1,  0,  0,  1,  0
             * 割り切り(0) ：  1,  -,  2,  3,  -,  4 = 10回
             * 割り切り(1) ：  -,  0,  -,  -,  1,  - =  1回
             * 割り切り合計：                          11回
             * 
             * 割り切り(1)の5箱目で1回としている意味。
             * ⇒割り切り(1)の2箱目で  5 % 2 = 1となり割り切れていない状態から
             * 　割り切り(1)の5箱目で 15 % 2 = 1としている。
             * 　これは3箱目～5箱目の合計が10(5, 4, 1)であるため、
             * 　10 % 2 = 0で割り切れる状態が発生したことを表し、
             * 　割り切り回数 1回としてカウントされているため。
             * 
             * 補足：標準入力の値が異常値の場合の考慮は省略しているため、
             * 　　　入力値Nは使用していない。
             */

            // お菓子の合計を取得する。
            var sumBoxes = GetSumBoxes(boxes);

            // お菓子の剰余の割り切りを取得する。
            var modNums = GetModNums(sumBoxes, m);

            // 割り切り合計を取得する。
            var ans = GetDivSum(modNums);

            // 標準出力を返す
            Console.WriteLine(ans);
        }

        /// <summary>
        /// お菓子の合計を取得する。
        /// </summary>
        /// <param name="boxes">お菓子の入数</param>
        /// <returns></returns>
        public static IEnumerable<long> GetSumBoxes(IEnumerable<long> boxes)
        {
            var sumBoxes = new List<long>();
            var sum = 0L;
            boxes.ToList().ForEach(num =>
            {
                sum += num;
                sumBoxes.Add(sum);
            });

            return sumBoxes;
        }

        /// <summary>
        /// お菓子の剰余を取得する。
        /// </summary>
        /// <param name="sum">お菓子の合計</param>
        /// <returns></returns>
        public static IEnumerable<long> GetModNums(IEnumerable<long> sum, long m)
        {
            var modNums = sum.Select(num => num % m);

            return modNums;
        }

        /// <summary>
        /// 割り切り合計を取得する。
        /// </summary>
        /// <param name="modNums">お菓子の剰余</param>
        /// <returns></returns>
        public static long GetDivSum(IEnumerable<long> modNums)
        {
            var divSum = 0L;
            var modCountDict = new Dictionary<long, long>();
            // 
            modNums.ToList().ForEach(modNum =>
            {
                // 剰余の発生回数の取得
                if (modCountDict.ContainsKey(modNum))
                {
                    modCountDict[modNum]++;
                } else
                {
                    if (modNum == 0L)
                    {
                        // 剰余0は発生時に割り切りとなるため、1開始
                        modCountDict.Add(modNum, 1L);
                    } else
                    {
                        modCountDict.Add(modNum,0L);
                    }
                }
                // 割り切り合計への加算
                divSum += modCountDict[modNum];
            });

            return divSum;
        }
    }
}

Measured memory_bytes: 28000