#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
const int md = 998244353;
const ll INF = 1e18;
void self_mul(ll &a, ll b) { a = (a % md * b % md) % md; }
void self_add(ll &a, ll b) { a = (a % md + b % md) % md; }
void self_sub(ll &a, ll b) { a = (a % md - b % md + md) % md; }
ll pw(ll a, ll b) {
  ll ans = 1;
  while (b) {
    if (b & 1) {
      ans = ans * a;
    }
    a = a * a;
    b = b >> 1;
  }
  return ans;
}
ll pwmd(ll a, ll b) {
  ll ans = 1;
  while (b) {
    if (b & 1) {
      self_mul(ans, a);
    }
    self_mul(a, a);
    b = b >> 1;
  }
  return ans;
}
int my_log(ll n, int b) {
  int ans = -1;
  while (n) {
    n /= b;
    ans++;
  }
  return ans;
}
ll my_ceil(ll a, ll b) { return (a + b - 1) / b; }
ll invmod(ll n) { return pwmd(n, md - 2); }
const int mxN = 5e5 + 10;
int n, m, k;
int a[mxN];
vector<int> adj[mxN], group[mxN];
vector<int> valid(mxN), vis(mxN), rep(mxN), col(mxN);
vector<pair<int, int>> edges(mxN);
map<pair<int, int>, vector<pair<int, int>>> vec[mxN][2];
map<pair<int, int>, vector<pair<int, int>>> con;
map<pair<int, int>, bool> mark;
map<pair<int, int>, int> cols;
int dfs(int u, int g, int c, int r) {
  vis[u] = 1;
  col[u] = c;
  rep[u] = r;
  int inv = 3 - c;
  int flag = 1;
  for (auto k : adj[u]) {
    if (a[k] != g) continue;
    if (vis[k]) {
      if (col[k] == col[u]) return false;
      continue;
    }
    flag &= dfs(k, g, inv, r);
  }
  return flag;
}
int check_bipartite(int n) {
  for (auto k : group[n]) {
    col[k] = 0;
    vis[k] = 0;
    rep[k] = 0;
  }
  int flag = 1;
  for (auto i : group[n]) {
    if (!vis[i]) {
      flag &= dfs(i, n, 1, i);
    }
  }
  return flag;
}
bool dfs2(pair<int, int> point, pair<int, int> gp) {
  mark[point] = true;
  if (mark[make_pair(point.first, 3 - point.second)]) {
    if (cols[make_pair(point.first, 3 - point.second)] == cols[point]) {
      return true;
    }
  } else {
    cols[make_pair(point.first, 3 - point.second)] = 3 - cols[point];
    if (dfs2(make_pair(point.first, 3 - point.second), gp)) return true;
  }
  for (auto k : vec[point.first][point.second][gp]) {
    if (mark[k]) {
      if (cols[k] == cols[point]) return true;
      continue;
    }
    cols[k] = 3 - cols[point];
    if (dfs2(k, gp)) return true;
  }
  return false;
}
pair<int, int> get(int a, int b) { return make_pair(min(a, b), max(a, b)); }
pair<int, int> get(pair<int, int> p) {
  return make_pair(min(p.first, p.second), max(p.first, p.second));
}
void test_case() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < n; i++) {
    scanf("%d", &a[i]);
    --a[i];
    group[a[i]].push_back(i);
  }
  for (int i = 0, u, v; i < m; i++) {
    scanf("%d%d", &u, &v), --u, --v;
    adj[u].push_back(v);
    adj[v].push_back(u);
    edges[i] = get(u, v);
  }
  int s = 0;
  for (int i = 0; i < k; i++) {
    valid[i] = check_bipartite(i);
    s += valid[i];
  }
  for (int i = 0; i < m; i++) {
    int x = edges[i].first, y = edges[i].second;
    if (a[x] == a[y] || !valid[a[x]] || !valid[a[y]]) continue;
    int colx = col[x], coly = col[y];
    x = rep[x];
    y = rep[y];
    pair<int, int> gp = make_pair(a[x], a[y]);
    if (gp.first > gp.second) {
      swap(x, y);
      swap(colx, coly);
    }
    gp = get(gp);
    vec[x][colx][gp].push_back(make_pair(y, coly));
    vec[y][coly][gp].push_back(make_pair(x, colx));
    con[gp].push_back(make_pair(x, colx));
    con[gp].push_back(make_pair(y, coly));
  }
  int invalid = 0;
  for (auto m : con) {
    vector<pair<int, int>> points = m.second;
    mark.clear();
    cols.clear();
    for (auto kk : points) {
      if (mark[kk]) continue;
      cols[kk] = kk.second;
      if (dfs2(kk, m.first)) {
        invalid++;
        break;
      }
    }
  }
  printf("%lld\n", s * (ll)(s - 1) / 2 - invalid);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  int t = 1;
  for (int tt = 1; tt <= t; tt++) {
    test_case();
  }
  return 0;
}
