#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
int gp[maxn];
int bz_tag[maxn];
stack<pair<int*, int> > stk;
int pre[maxn], w[maxn], rnk[maxn];
inline void init_dsu(int n) {
  memset(rnk, 0, sizeof(rnk));
  for (int i = 1; i <= n; ++i) {
    pre[i] = i;
  }
}
inline int Findpre(int u) {
  while (u != pre[u]) {
    u = pre[u];
  }
  return u;
}
inline int get_dis(int u) {
  int ans = 0;
  while (pre[u] != u) {
    ans ^= w[u];
    u = pre[u];
  }
  return ans;
}
inline void cancel() {
  *stk.top().first = stk.top().second;
  stk.pop();
}
inline void Union(int x, int y, int dis, bool isc) {
  x = Findpre(x), y = Findpre(y);
  if (x == y) return;
  if (rnk[x] > rnk[y]) swap(x, y);
  if (rnk[x] == rnk[y]) {
    if (isc) stk.push(make_pair(rnk + y, rnk[y]));
    ++rnk[y];
  }
  int lastw_x = w[x];
  if (isc) {
    stk.push(make_pair(pre + x, pre[x]));
    stk.push(make_pair(w + x, w[x]));
  }
  pre[x] = y, w[x] = dis;
}
int main() {
  long long n, m, k;
  cin >> n >> m >> k;
  init_dsu(n);
  for (int i = 1; i <= n; ++i) cin >> gp[i];
  vector<pair<pair<int, int>, pair<int, int> > > e;
  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    if (gp[a] > gp[b]) swap(a, b);
    if (gp[a] == gp[b]) {
      int fa = Findpre(a), fb = Findpre(b), disa = get_dis(a),
          disb = get_dis(b);
      if (fa != fb) {
        Union(fa, fb, disa ^ disb ^ 1, false);
      } else if (fa == fb) {
        if (disa == disb && !bz_tag[gp[a]]) --k, bz_tag[gp[a]] = 1;
      }
    } else {
      e.push_back(make_pair(make_pair(gp[a], gp[b]), make_pair(a, b)));
    }
  }
  long long cc = k * (k - 1) / 2;
  sort(e.begin(), e.end());
  bool iscancel = false;
  for (int i = 0; i < e.size(); ++i) {
    if (i) {
      if (gp[e[i].second.first] != gp[e[i - 1].second.first] ||
          gp[e[i].second.second] != gp[e[i - 1].second.second]) {
        while (!stk.empty()) {
          cancel();
        }
        iscancel = false;
      }
    }
    if (iscancel) continue;
    if (bz_tag[gp[e[i].second.first]] || bz_tag[gp[e[i].second.second]])
      continue;
    int u = Findpre(e[i].second.first), v = Findpre(e[i].second.second);
    int disu = get_dis(e[i].second.first), disv = get_dis(e[i].second.second);
    if (u == v) {
      if (disu == disv) {
        iscancel = true, --cc;
      }
    } else {
      Union(u, v, disu ^ disv ^ 1, true);
    }
  }
  cout << cc << endl;
  return 0;
}
