#include <bits/stdc++.h>
const int maxn = 100010;
const int maxm = 200010;
using namespace std;
struct Tarjan {
  int head[maxn], node[maxm], nex[maxm], top, n;
  void clr() {
    top = 0;
    memset(head, -1, sizeof(head));
    memset(nex, 0, sizeof(nex));
  }
  void addedge(int u, int v) {
    node[top] = v;
    nex[top] = head[u];
    head[u] = top++;
  }
  int low[maxn], dfn[maxn], sz[maxn], scc[maxn], stack[maxn], dout[maxn],
      scccnt, times;
  void dfs(int u) {
    low[u] = dfn[u] = ++times;
    stack[++stack[0]] = u;
    for (int tmp = head[u]; tmp != -1; tmp = nex[tmp]) {
      int v = node[tmp];
      if (!dfn[v]) {
        dfs(v);
        if (low[v] < low[u]) low[u] = low[v];
      } else if (!scc[v] && dfn[v] < low[u])
        low[u] = dfn[v];
    }
    if (dfn[u] == low[u]) {
      scccnt++;
      while (1) {
        int v = stack[stack[0]--];
        scc[v] = scccnt;
        sz[scccnt]++;
        if (v == u) break;
      }
    }
  }
  void calc() {
    for (int i = 1; i <= n; i++)
      for (int j = head[i]; j != -1; j = nex[j]) {
        int v = node[j];
        if (scc[i] != scc[v]) dout[scc[i]]++;
      }
    int Ans = 1e9, t = 0;
    for (int i = 1; i <= scccnt; i++)
      if (!dout[i] && sz[i] < Ans) Ans = sz[i], t = i;
    printf("%d\n", Ans);
    for (int i = 1; i <= n; i++)
      if (scc[i] == t) printf("%d ", i);
  }
  void getscc() {
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(scc, 0, sizeof(scc));
    stack[0] = 0;
    scccnt = 0;
    times = 0;
    for (int i = 1; i <= n; i++)
      if (!dfn[i]) dfs(i);
  }
} G;
int w[maxn];
int n, m, h;
int main() {
  scanf("%d%d%d", &n, &m, &h);
  G.n = n;
  G.clr();
  for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    if ((w[u] + 1) % h == w[v]) G.addedge(u, v);
    if ((w[v] + 1) % h == w[u]) G.addedge(v, u);
  }
  G.getscc();
  G.calc();
  return 0;
}
