use std::collections::HashMap;
use std::cmp::Ordering;


fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
        .map(|e| e.parse().ok().unwrap()).collect()
}

pub trait BinarySearch<T> {
    fn upper_bound(&self, &T) -> usize;
}

impl<T: Ord> BinarySearch<T> for [T] {
    fn upper_bound(&self, x: &T) -> usize {
        let mut low = 0;
        let mut high = self.len();

        while low != high {
            let mid = (low + high) / 2;
            match self[mid].cmp(x) {
                Ordering::Less | Ordering::Equal => {
                    low = mid + 1;
                }
                Ordering::Greater => {
                    high = mid;
                }
            }
        }
        low
    }
}

fn main() {
    let a: Vec<i64> = read_vec();
    let n: usize = a[0] as usize;
    let m: i64 = a[1];

    let a: Vec<i64> = read_vec();
    let mut accum = vec![0i64; n];
    accum[0] = a[0] % m;

    for i in 1..n {
        accum[i] = (accum[i - 1] + a[i]) % m;
    }
    let accum = accum;

    // println!("accum {:?}", accum);

    let mut rev_accum = vec![0i64; n + 1];
    rev_accum[n] = 0;
    rev_accum[n-1] = a[n-1] % m;

    for i in (0..n-1).rev() {
        rev_accum[i] = (rev_accum[i + 1] + a[i]) % m;
    }
    let rev_accum = rev_accum;

    // println!("rev_accum {:?}", rev_accum);

    let mut map = HashMap::new();
    for i in 0..n + 1 {
        (*map.entry(rev_accum[i]).or_insert(vec![])).push(i);
    }

    // println!("map {:?}", map);

    let mut ans: usize = 0;
    {
        let res: i64 = accum[n - 1] % m;
        let matched: &Vec<usize> = map.entry(res).or_insert(vec![]);
        ans += matched.len() - matched.upper_bound(&(1));
    }
    for i in 0..n {
        let res: i64 = (accum[n - 1] - accum[i] + m) % m;
        let matched: &Vec<usize> = map.entry(res).or_insert(vec![]);
        ans += matched.len() - matched.upper_bound(&(i + 1));
        /*
        println!("i:{3} :res:{0} len:{1} upper:{2}",
                 res, matched.len(), matched.upper_bound(&i), i);
        println!("{:?}", matched);
        */
    }
    println!("{:?}", ans);
}
