#include <bits/stdc++.h>
using namespace std;
#define start_routine cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(false); int begtime = clock();
#define end_routine int endtime = clock(); cerr << endl << "Time elapsed: " << (endtime - begtime)*1000/CLOCKS_PER_SEC << " ms"; return 0
#define endl '\n'
#define contests_de_diya_kar 0
#define PB push_back
#define MP make_pair
#define int long long
#define MOD ((long long) (1000*1000*1000 + 7))
#define inf (int) 2e15
#define exit(a, b) return cout << a, b;
#define eps (double)1e-8
#define forn(a, b, i) for (int i = a; i < b; i += 1)
#define vi vector<int>
#define vb vector<bool>
#define all(v) v.begin(), v.end() 
#define pii pair<int, int>
#define mii map<int, int> 
#define print(stuff) cout << stuff << endl
#define len(stuff) stuff.size()

vector<pair<int, int>> tree;
vector<int> arr;
pair<int, int> qans(MP(-inf, -inf));

void build (int l, int r, int node) {
	if (l == r) {
		tree[node].first = arr[l];
		tree[node].second = -inf;
		return;
	} 
	int mid = (l + r) / 2;
	build(l, mid, 2 * node + 1);
	build(mid + 1, r, 2 * node + 2);
	vi te;
	te.push_back(tree[2 * node + 1].first);
	te.push_back(tree[2 * node + 2].first);
	te.push_back(tree[2 * node + 1].second);
	te.push_back(tree[2 * node + 2].second);

	sort(all(te));
	reverse(all(te));
	tree[node].first = te[0];
	tree[node].second = te[1];
}

void update (int l, int r, int node, int idx, int x) {
	if (l > idx or r < idx) return;
	if (l == r) {
		tree[node].first = x;
		tree[node].second = -inf;
		return;
	}
	int mid = (l + r) / 2;
	update (l, mid, 2 * node + 1, idx, x);
	update (mid + 1, r, 2 * node + 2, idx, x);
	vi te;
	te.push_back(tree[2 * node + 1].first);
	te.push_back(tree[2 * node + 2].first);
	te.push_back(tree[2 * node + 1].second);
	te.push_back(tree[2 * node + 2].second);

	sort(all(te));
	reverse(all(te));
	tree[node].first = te[0];
	tree[node].second = te[1];
}

void query (int l, int r, int node, int lu, int ru) {
	if (l > lu or r < lu) return;
	if (l >= lu and r <= ru) {
		vi te;
		te.push_back(qans.first);
		te.push_back(qans.second);
		te.push_back(tree[node].first);
		te.push_back(tree[node].second);

		sort(all(te));
		reverse(all(te));
		qans.first = te[0], qans.second = te[1];
		return;
	}
	int mid = (l + r) / 2;
	query (l, mid, 2 * node + 1, lu, ru);
	query (mid + 1, r, 2 * node + 2, lu, ru);
}
//  Utility method to convert integer into string
string toString(int n)
{
    string str;
    stringstream ss;
    ss << n;
    ss >> str;
    return str;
}
 
// Method to convert n to base negBase
string toNegativeBase(int n, int negBase)
{
    //  If n is zero then in any base it will be 0 only
    if (n == 0)
        return "0";
 
    string converted = "";
    while (n != 0)
    {
        // Get remainder by negative base, it can be
        // negative also
        int remainder = n % negBase;
        n /= negBase;
 
        // if remainder is negative, add abs(base) to
        // it and add 1 to n
        if (remainder < 0)
        {
            remainder += (-negBase);
            n += 1;
        }
 
        // convert remainder to string add into the result
        converted = toString(remainder) + converted;
    }
 
    return converted;
}
 

signed main () {
	start_routine;
	#ifndef ONLINE_JUDGE
	//freopen("input.txt", "r", stdin);
	#endif

	mii ct;
	int n;
	cin >> n;

	int m;
	cin >> m;

	int s = 0;
	for (int i = 0; i < n; i += 1) {
		int a;
		cin >> a;

		s += a;
		s %= m;
		ct[s] += 1;
	}

	int ans = 0;
	for (auto p: ct) {
		ans += (p.second * (p.second - 1)) / 2;
	}
	ans += ct[0];
	cout << ans << endl;
	end_routine;
}


Measured memory_bytes: 4224