#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template <class T>
struct rge {
  T b, e;
};
template <class T>
rge<T> range(T i, T j) {
  return rge<T>{i, j};
}
template <class T>
auto dud(T *x) -> decltype(cerr << *x, 0);
template <class T>
char dud(...);
struct debug {
  template <class T>
  debug &operator<<(const T &) {
    return *this;
  }
};
struct Dsu {
  vector<int> pr, tot;
  Dsu(int n = 0) : pr(n + 5), tot(n + 5, 1) { iota(begin(pr), end(pr), 0); }
  int find(int u) { return pr[u] == u ? u : pr[u] = find(pr[u]); }
  void unite(int u, int v) {
    u = find(u), v = find(v);
    if (u != v) pr[v] = u, tot[u] += tot[v];
  }
  bool same(int u, int v) { return find(u) == find(v); }
  int operator[](int u) { return find(u); }
} dsu;
const int N = 1e5 + 5, inf = 2e9;
vector<int> graph[N], dag[N];
int tin[N], fup[N];
bool still[N];
stack<int> stk;
int timer = 0;
void tarjan(int u) {
  tin[u] = fup[u] = ++timer;
  still[u] = true;
  stk.push(u);
  for (int v : graph[u]) {
    if (!tin[v]) tarjan(v);
    if (still[v]) fup[u] = min(fup[u], fup[v]);
  }
  if (fup[u] == tin[u]) {
    int v;
    do {
      v = stk.top();
      stk.pop();
      still[v] = false;
      dsu.unite(u, v);
    } while (v != u);
  }
}
int n, m, h, off[N], outdeg[N];
struct Edge {
  int u, v;
};
vector<Edge> edges;
void reset() {
  for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
       u += 1 - 2 * ((1) > (n + 1))) {
    graph[u].clear();
    tin[u] = fup[u] = still[u] = off[u] = outdeg[u] = 0;
  }
  timer = 0;
  stk = stack<int>();
  dsu = Dsu(n);
  edges.clear();
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  while (cin >> n >> m >> h) {
    reset();
    for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
         u += 1 - 2 * ((1) > (n + 1)))
      cin >> off[u];
    while (m--) {
      int u, v;
      cin >> u >> v;
      if ((off[u] + 1) % h == off[v])
        graph[u].push_back(v), edges.push_back({u, v});
      if ((off[v] + 1) % h == off[u])
        graph[v].push_back(u), edges.push_back({v, u});
    }
    for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
         u += 1 - 2 * ((1) > (n + 1)))
      if (!tin[u]) tarjan(u);
    for (auto e : edges) {
      int u = dsu[e.u], v = dsu[e.v];
      if (!dsu.same(u, v)) dag[u].push_back(v), outdeg[u]++;
    }
    debug() << " "
            << "range(outdeg + 1, outdeg + n + 1)"
               ": "
            << (range(outdeg + 1, outdeg + n + 1)) << " ";
    for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
         u += 1 - 2 * ((1) > (n + 1)))
      debug() << " "
              << "dag[u]"
                 ": "
              << (dag[u]) << " ";
    int mn = inf, id;
    for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
         u += 1 - 2 * ((1) > (n + 1)))
      if (u == dsu[u])
        if (dsu.tot[u] < mn && !outdeg[u]) mn = dsu.tot[u], id = u;
    cout << mn << '\n';
    for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
         u += 1 - 2 * ((1) > (n + 1)))
      if (dsu[u] == id) cout << u << " ";
    cout << '\n';
  }
  return 0;
}
