#include <bits/stdc++.h>
using namespace std;
struct roll {
  int node[2];
  int d[2];
  int mrank[2];
};
int mrank[500005], dsu[500005], d[500005];
pair<int, int> f(int x) {
  if (x == dsu[x]) {
    return {x, 0};
  }
  pair<int, int> r = f(dsu[x]);
  r.second ^= d[x];
  return r;
}
stack<roll> rst;
bool merge(int a, int b) {
  pair<int, int> ex = f(a), ey = f(b);
  int x = ex.first, y = ey.first;
  if (x != y) {
    if (mrank[x] > mrank[y]) {
      swap(x, y);
    }
    roll tmp;
    tmp.node[0] = x, tmp.node[1] = y;
    tmp.d[0] = d[x], tmp.d[1] = d[y];
    tmp.mrank[0] = mrank[x], tmp.mrank[1] = mrank[y];
    rst.push(tmp);
    dsu[x] = y;
    if (mrank[x] == mrank[y]) {
      ++mrank[y];
    }
    d[x] = ex.second == ey.second;
    return true;
  } else {
    return ex.second != ey.second;
  }
}
void rollback() {
  roll tmp = rst.top();
  rst.pop();
  for (int i = 0; i < 2; ++i) {
    dsu[tmp.node[i]] = tmp.node[i];
    d[tmp.node[i]] = tmp.d[i];
    mrank[tmp.node[i]] = tmp.mrank[i];
  }
}
int group[500005];
long long getGroupId(int a, int b, int k) {
  if (a > b) {
    swap(a, b);
  }
  return (long long)group[a] * (k + 1) + group[b];
}
vector<pair<int, int> > edge[500005];
vector<pair<int, pair<int, int> > > dedge[500005];
bool isBad[500005];
void solve() {
  int n, m, inK;
  scanf("%d %d %d ", &n, &m, &inK);
  for (int i = 1; i <= n; ++i) {
    scanf("%d ", &group[i]);
    dsu[i] = i;
  }
  for (int i = 0; i < m; ++i) {
    int a, b;
    scanf("%d %d ", &a, &b);
    if (group[a] == group[b]) {
      edge[group[a]].push_back({a, b});
    } else {
      dedge[group[a]].push_back({group[b], {a, b}});
      dedge[group[b]].push_back({group[a], {a, b}});
    }
  }
  int numBiparate = 0;
  for (int i = 1; i <= inK; ++i) {
    sort(dedge[i].begin(), dedge[i].end());
    for (pair<int, int> e : edge[i]) {
      isBad[i] |= !merge(e.first, e.second);
    }
    if (!isBad[i]) {
      ++numBiparate;
    }
  }
  long long ret = 0;
  for (int i = 1; i <= inK; ++i) {
    if (isBad[i]) {
      continue;
    }
    int numGood = numBiparate - 1;
    for (int j = 0; j < dedge[i].size();) {
      int ed, k;
      for (k = j; k < dedge[i].size(); ++k) {
        if (dedge[i][k].first != dedge[i][j].first) {
          break;
        }
      }
      ed = k;
      if (!isBad[dedge[i][j].first]) {
        --numGood;
        int cur = rst.size();
        bool curGood = true;
        for (k = j; k < dedge[i].size(); ++k) {
          if (dedge[i][k].first != dedge[i][j].first) {
            break;
          }
          if (!merge(dedge[i][k].second.first, dedge[i][k].second.second)) {
            curGood = false;
            break;
          }
        }
        while (cur < rst.size()) {
          rollback();
        }
        if (curGood) {
          ++ret;
        }
      }
      j = ed;
    }
    ret += numGood;
  }
  assert(ret % 2 == 0);
  printf("%lld\n", ret / 2);
}
int main() {
  solve();
  return 0;
}
