#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 10;
const int MAXM = 4e6 + 10;
const long long MOD = 998244353;
const long long INF = 0x3f3f3f3f;
const unsigned long long BASE = 233;
const int base = 5;
mt19937_64 mt(time(0));
char rubbish[110];
bool GETDATA;
inline long long read() {
  long long x = 0, f = 1;
  char ch;
  do {
    ch = getchar();
    if (ch == '-') f = -1;
  } while (ch < '0' || ch > '9');
  do {
    x = x * 10 + ch - 48;
    ch = getchar();
  } while (ch >= '0' && ch <= '9');
  return x * f;
}
inline void write(long long x, char con = '\n') {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10, 0);
  putchar(x % 10 + '0');
  if (con) putchar(con);
}
long long N, M, K, Q;
long long c[MAXN];
pair<int, int> es[MAXN];
int S[MAXM];
int sz[MAXM];
pair<int, int> n[MAXM];
int idx[MAXM];
int tot;
bool able[MAXN];
map<pair<int, int>, int> dic;
vector<int> con[MAXN];
int Find(int x) { return S[x] == x ? x : Find(S[x]); }
void Union(int u, int v) {
  u = Find(u);
  v = Find(v);
  if (sz[u] > sz[v]) {
    swap(u, v);
  }
  n[++tot].first = S[u];
  n[tot].second = sz[u];
  idx[tot] = u;
  n[++tot].first = S[v];
  n[tot].second = sz[v];
  idx[tot] = v;
  sz[v] += sz[u];
  S[u] = v;
}
void init() {
  for (int i = 2 * N; i >= 1; i--) {
    S[i] = i;
    sz[i] = 1;
  }
  for (int i = 1; i <= K; i++) {
    able[i] = true;
  }
  for (int i = 1; i <= M; i++) {
    con[i].clear();
  }
  tot = 0;
}
void solve() {
  long long ans = 0;
  int u, v, val;
  int temp;
  int uu, vv, uuu, vvv;
  N = read();
  M = read();
  K = read();
  init();
  for (int i = 1; i <= N; i++) {
    c[i] = read();
  }
  for (int i = 1; i <= M; i++) {
    es[i] = {read(), read()};
  }
  for (int i = 1; i <= M; i++) {
    if (c[es[i].first] == c[es[i].second]) {
      u = Find(es[i].first);
      v = Find(es[i].second);
      if (u == v) {
        able[c[es[i].first]] = false;
      } else {
        Union(es[i].first, es[i].second + N);
        Union(es[i].first + N, es[i].second);
      }
    }
  }
  for (int i = 1, j = 0; i <= M; i++) {
    if (c[es[i].first] != c[es[i].second] && able[c[es[i].first]] &&
        able[c[es[i].second]]) {
      u = c[es[i].first];
      v = c[es[i].second];
      if (u > v) {
        swap(u, v);
      }
      if (!dic.count({u, v})) {
        dic[{u, v}] = ++j;
      }
      con[dic[{u, v}]].push_back(i);
    }
  }
  for (int i = 1; i <= K; i++) {
    if (able[i]) {
      ans++;
    }
  }
  ans = ans * (ans - 1) / 2;
  for (auto x : dic) {
    u = x.first.first;
    v = x.first.second;
    val = x.second;
    temp = tot;
    for (auto y : con[val]) {
      uu = es[y].first;
      vv = es[y].second;
      uuu = Find(uu);
      vvv = Find(vv);
      if (uuu == vvv) {
        ans--;
        break;
      }
      Union(uu, vv + N);
      Union(uu + N, vv);
    }
    while (tot != temp) {
      S[idx[tot]] = n[tot].first;
      sz[idx[tot]] = n[tot].second;
      tot--;
    }
  }
  write(ans);
}
int main() {
  int T;
  T = 1;
  for (int t = 1; t <= T; t++) {
    GETDATA = false;
    solve();
  }
  return 0;
}
