#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
const int N = 1e6 + 5, M = 1000000007, INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
void Main();
void debug() { cerr << endl; }
template <typename T, typename... Ts>
void debug(T x, Ts... y) {
  cerr << "\033[31m" << x << "\033[0m";
  if (sizeof...(y) > 0) cerr << ' ';
  debug(y...);
}
template <typename T>
void debug(const T& a, int l, int r, char c) {
  for (int i = l; i <= r; ++i)
    cerr << "\033[31m" << a[i] << "\033[0m" << (i == r ? '\n' : c);
}
template <typename T>
void debug(vector<T> a) {
  for (int i = 0; i < (int)a.size(); ++i)
    cout << "\033[31m" << a[i] << "\033[0m"
         << " \n"[i == (int)a.size() - 1];
}
void print() { cout << '\n'; }
template <typename T, typename... Ts>
void print(T x, Ts... y) {
  cout << x;
  if (sizeof...(y) > 0) cout << ' ';
  print(y...);
}
template <typename T>
void print(const T& a, int l, int r, char c) {
  for (int i = l; i <= r; ++i) cout << a[i] << (i == r ? '\n' : c);
}
template <typename T>
void print(vector<T> a) {
  for (int i = 0; i < (int)a.size(); ++i)
    cout << a[i] << " \n"[i == (int)a.size() - 1];
}
void input() {}
template <typename T, typename... Ts>
void input(T& x, Ts&... y) {
  cin >> x;
  input(y...);
}
template <typename T>
void input(T* a, int l, int r) {
  for (int i = l; i <= r; ++i) cin >> a[i];
}
template <typename T>
void input(vector<T>& a, int l, int r) {
  for (int i = l; i <= r; ++i) cin >> a[i];
}
template <typename T>
void input(vector<T> a) {
  for (auto&& x : a) input(a);
}
template <typename T>
void Max(T& a, T b) {
  if (a < b) a = b;
}
template <typename T>
void Min(T& a, T b) {
  if (a > b) a = b;
}
template <typename T>
void Add(T& a, T b) {
  a += b;
  if (a > M) a -= M;
  if (a < 0) a += M;
}
template <typename T>
void Mul(T& a, T b) {
  a = a * b % M;
}
template <typename T>
T Mod(T a) {
  return (a % M + M) % M;
}
ll qpow(ll a, ll b) {
  ll ret = 1;
  while (b) {
    if (b & 1) ret = ret * a % M;
    a = a * a % M, b >>= 1;
  }
  return ret;
}
ll pinv(ll x, ll mod = M) { return qpow(x, mod - 2); }
template <typename... Args>
string sformat(const string& format, Args... args) {
  size_t size = snprintf(nullptr, 0, format.c_str(), args...) + 1;
  unique_ptr<char[]> buf(new char[size]);
  snprintf(buf.get(), size, format.c_str(), args...);
  return string(buf.get(), buf.get() + size - 1);
}
int main(int argc, char** argv) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  Main();
}
int col[N], col2[N], con[N], col3[N];
vector<int> G[N], V[N], g[N];
bitset<N> odd, vis, vis2;
void dfs(int u) {
  for (int v : G[u])
    if (!con[v]) {
      con[v] = con[u];
      col2[v] = col2[u] ^ 1;
      dfs(v);
    } else if (col2[v] == col2[u]) {
      odd[col[u]] = true;
    }
}
bool dfs2(int u) {
  bool ret = true;
  vis2[u] = true;
  for (int v : g[u])
    if (!vis2[v]) {
      col3[v] = col3[u] ^ 1;
      ret &= dfs2(v);
    } else if (col3[v] == col3[u])
      return false;
  return ret;
}
void Main() {
  int n, m, k;
  input(n, m, k);
  input(col, 1, n);
  for (int i = 1; i <= n; ++i) V[col[i]].push_back(i);
  vector<pii> edges;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    input(u, v);
    if (col[u] == col[v]) {
      G[u].push_back(v);
      G[v].push_back(u);
    } else {
      if (col[u] > col[v]) swap(u, v);
      edges.emplace_back(u, v);
    }
  }
  int cnt = 0;
  for (int i = 1; i <= k; ++i) {
    for (int u : V[i])
      if (!con[u]) {
        ++cnt;
        con[u] = cnt;
        dfs(u);
      }
  }
  cnt = 0;
  for (int i = 1; i <= k; ++i)
    if (odd[i]) ++cnt;
  ll ans = 1ll * (k - cnt) * (k - cnt - 1) / 2;
  sort(edges.begin(), edges.end(), [](pii a, pii b) {
    return col[a.first] < col[b.first] ||
           (col[a.first] == col[b.first] && col[a.second] < col[b.second]);
  });
  int tot = n;
  for (auto p = edges.begin(), p2 = p; p != edges.end(); p = next(p2)) {
    p2 = p;
    if (odd[col[p->first]] || odd[col[p->second]]) continue;
    while (next(p2) != edges.end() && col[p2->first] == col[next(p2)->first] &&
           col[p2->second] == col[next(p2)->second])
      ++p2;
    vector<int> nodes;
    for (auto p3 = p; p3 <= p2; ++p3) {
      auto [u, v] = *p3;
      if (col2[u] == col2[v]) {
        ++tot;
        g[con[u]].push_back(tot);
        g[con[v]].push_back(tot);
        g[tot].push_back(con[u]);
        g[tot].push_back(con[v]);
      } else {
        g[con[u]].push_back(con[v]);
        g[con[v]].push_back(con[u]);
      }
      if (!vis[con[u]]) {
        vis[con[u]] = true;
        nodes.push_back(con[u]);
      }
      if (!vis[con[v]]) {
        vis[con[v]] = true;
        nodes.push_back(con[v]);
      }
    }
    bool ok = true;
    for (int u : nodes)
      if (!vis2[u] && !dfs2(u)) {
        ok = false;
        break;
      }
    if (!ok) --ans;
    for (int u : nodes) {
      g[u].clear();
      vis[u] = vis2[u] = false;
    }
  }
  print(ans);
}
