#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int N = 1e6 + 10;
struct UFS {
  stack<pair<int *, int>> stk;
  int fa[N], rnk[N];
  inline void init(int n) {
    for (int i = 0; i <= n; ++i) fa[i] = i, rnk[i] = 0;
  }
  inline int Find(int x) {
    while (x ^ fa[x]) x = fa[x];
    return x;
  }
  inline void Merge(int x, int y) {
    x = Find(x), y = Find(y);
    if (x == y) return;
    if (rnk[x] <= rnk[y]) {
      stk.push({fa + x, fa[x]});
      fa[x] = y;
      if (rnk[x] == rnk[y]) {
        stk.push({rnk + y, rnk[y]});
        rnk[y]++;
      }
    } else {
      stk.push({fa + y, fa[y]});
      fa[y] = x;
    }
  }
  inline void Undo() {
    *stk.top().first = stk.top().second;
    stk.pop();
  }
} ufs;
struct Edge {
  int u, v;
};
int main() {
  int n, m, k;
  cin >> n >> m >> k;
  vector<int> c(n + 1);
  for (int i = 1; i <= n; i++) cin >> c[i];
  vector<Edge> same_edges;
  map<pair<int, int>, vector<Edge>> diff_edges;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    if (c[u] == c[v])
      same_edges.push_back({u, v});
    else {
      if (c[u] > c[v]) swap(u, v);
      diff_edges[{c[u], c[v]}].push_back({u, v});
    }
  }
  vector<int> group_flag(k + 1, 1);
  ufs.init((n + 1) * 2);
  for (auto &[u, v] : same_edges) {
    ufs.Merge(u * 2, v * 2 + 1);
    ufs.Merge(u * 2 + 1, v * 2);
    if (ufs.Find(u * 2) == ufs.Find(u * 2 + 1)) group_flag[c[u]] = 0;
    if (ufs.Find(v * 2) == ufs.Find(v * 2 + 1)) group_flag[c[v]] = 0;
  }
  ll good_group_cnt = 0;
  for (int i = 1; i <= k; i++)
    if (group_flag[i]) good_group_cnt++;
  ll cnt_fail = 0;
  for (auto &[key, row] : diff_edges) {
    if (!group_flag[key.first]) continue;
    if (!group_flag[key.second]) continue;
    int mark = (int)ufs.stk.size();
    int flag = 1;
    for (auto &[u, v] : row) {
      ufs.Merge(u * 2, v * 2 + 1);
      ufs.Merge(u * 2 + 1, v * 2);
      if (ufs.Find(u * 2) == ufs.Find(u * 2 + 1)) flag = 0;
      if (ufs.Find(v * 2) == ufs.Find(v * 2 + 1)) flag = 0;
    }
    if (!flag) cnt_fail++;
    while ((int)ufs.stk.size() > mark) {
      ufs.Undo();
    }
  }
  ll ans = good_group_cnt * (good_group_cnt - 1) / 2;
  ans = ans - cnt_fail;
  cout << ans;
}
