#include <bits/stdc++.h>
using namespace std;
template <class T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
namespace input {
template <class T>
void re(complex<T>& x);
template <class T1, class T2>
void re(pair<T1, T2>& p);
template <class T>
void re(vector<T>& a);
template <class T, size_t SZ>
void re(array<T, SZ>& a);
template <class T>
void reA(T A[], int sz);
template <class T>
void re(T& x) {
  cin >> x;
}
void re(double& x) {
  string t;
  re(t);
  x = stod(t);
}
void re(long double& x) {
  string t;
  re(t);
  x = stold(t);
}
template <class Arg, class... Args>
void re(Arg& first, Args&... rest) {
  re(first);
  re(rest...);
}
template <class T1, class T2>
void re(pair<T1, T2>& p) {
  re(p.first, p.second);
}
template <class T>
void re(vector<T>& a) {
  for (int i = 0; i < ((int)a.size()); i++) re(a[i]);
}
template <class T, size_t SZ>
void re(array<T, SZ>& a) {
  for (int i = 0; i < (SZ); i++) re(a[i]);
}
template <class T>
void reA(T A[], int sz) {
  for (int i = 0; i < (sz); i++) re(A[i]);
}
void setupIO(const string& PROB = "") {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  if (PROB.length() != 0) {
    ifstream infile(PROB + ".in");
    if (infile.good()) {
      freopen((PROB + ".in").c_str(), "r", stdin);
      freopen((PROB + ".out").c_str(), "w", stdout);
    }
  }
}
}  // namespace input
using namespace input;
namespace output {
template <class T1, class T2>
void prD(const pair<T1, T2>& x);
template <class T, size_t SZ>
void prD(const array<T, SZ>& x);
template <class T>
void prD(const vector<T>& x);
template <class T>
void prD(const set<T>& x);
template <class T1, class T2>
void prD(const map<T1, T2>& x);
template <class T1, class T2>
void pr(const pair<T1, T2>& x);
template <class T, size_t SZ>
void pr(const array<T, SZ>& x);
template <class T>
void pr(const vector<T>& x);
template <class T>
void pr(const set<T>& x);
template <class T1, class T2>
void pr(const map<T1, T2>& x);
template <class T>
void prD(const T& x) {
  cout << x;
}
template <class Arg, class... Args>
void prD(const Arg& first, const Args&... rest) {
  prD(first);
  prD(rest...);
}
template <class T1, class T2>
void prD(const pair<T1, T2>& x) {
  prD("{", x.first, ", ", x.second, "}");
}
template <class T>
void prDContain(const T& x) {
  prD("{");
  bool fst = 1;
  for (const auto& a : x) prD(!fst ? ", " : "", a), fst = 0;
  prD("}");
}
template <class T, size_t SZ>
void prD(const array<T, SZ>& x) {
  prDContain(x);
}
template <class T>
void prD(const vector<T>& x) {
  prDContain(x);
}
template <class T>
void prD(const set<T>& x) {
  prDContain(x);
}
template <class T1, class T2>
void prD(const map<T1, T2>& x) {
  prDContain(x);
}
void psD() { prD("\n"); }
template <class Arg>
void psD(const Arg& first) {
  prD(first);
  psD();
}
template <class Arg, class... Args>
void psD(const Arg& first, const Args&... rest) {
  prD(first, " ");
  psD(rest...);
}
template <class T>
void pr(const T& x) {
  cout << x;
}
template <class Arg, class... Args>
void pr(const Arg& first, const Args&... rest) {
  pr(first);
  pr(rest...);
}
template <class T1, class T2>
void pr(const pair<T1, T2>& x) {
  pr(x.first, " ", x.second);
}
template <class T>
void prContain(const T& x) {
  bool fst = 1;
  for (const auto& a : x) pr(!fst ? " " : "", a), fst = 0;
}
template <class T, size_t SZ>
void pr(const array<T, SZ>& x) {
  prContain(x);
}
template <class T>
void pr(const vector<T>& x) {
  prContain(x);
}
template <class T>
void pr(const set<T>& x) {
  prContain(x);
}
template <class T1, class T2>
void pr(const map<T1, T2>& x) {
  prContain(x);
}
void ps() { pr("\n"); }
template <class Arg>
void ps(const Arg& first) {
  pr(first);
  ps();
}
template <class Arg, class... Args>
void ps(const Arg& first, const Args&... rest) {
  pr(first, " ");
  ps(rest...);
}
}  // namespace output
using namespace output;
int n, p, k;
long long conv(long long x) {
  return (((x * x % p * x % p * x % p - k * x % p) % p) + p) % p;
}
int main() {
  setupIO();
  re(n, p, k);
  int A[n];
  reA(A, n);
  map<long long, int> ct;
  for (int i = 0; i < (n); i++) {
    ct[conv(A[i])]++;
  }
  long long ans = 0;
  for (auto x : ct) {
    ans += ct[x.first] * (ct[x.first] - 1) / 2;
  }
  ps(ans);
  return 0;
}
