#include <bits/stdc++.h>
using namespace std;
const int MAX_INT = 1 << 30;
const int maxn = 1e5 + 10;
struct Node {
  int u, v;
};
Node edge[2 * maxn];
int n, m, h;
int ecnt, number, dfstime;
int head[maxn], u[maxn], vis[maxn], inst[maxn];
int belong[maxn], low[maxn], dfn[maxn];
int out[maxn], getsum[maxn], f[maxn];
stack<int> sta;
void addEdge(int u, int v) {
  ecnt++;
  edge[ecnt].u = u;
  edge[ecnt].v = v;
}
bool cmp(Node a, Node b) {
  if (a.u != b.u) return a.u < b.u;
  return a.v < b.v;
}
void dfs(int x) {
  dfn[x] = low[x] = ++dfstime;
  vis[x] = 1;
  sta.push(x);
  inst[x] = 1;
  for (int i = f[x]; i < f[x + 1]; i++) {
    int v = edge[i].v;
    if (!vis[v]) {
      dfs(v);
      low[x] = min(low[x], low[v]);
    } else if (inst[v])
      low[x] = min(low[x], dfn[v]);
  }
  if (low[x] == dfn[x]) {
    while (!sta.empty()) {
      int u = sta.top();
      sta.pop();
      inst[u] = 0;
      belong[u] = number;
      if (u == x) break;
    }
    number++;
  }
}
int tarjan() {
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i);
  while (!sta.empty()) {
    int u = sta.top();
    sta.pop();
    belong[u] = number;
  }
  memset(getsum, 0, sizeof(getsum));
  for (int i = 1; i <= n; i++) getsum[belong[i]]++;
  memset(out, 0, sizeof(out));
  for (int i = 1; i <= n; i++)
    for (int j = f[i]; j < f[i + 1]; j++) {
      int v = edge[j].v;
      if (j != f[i] && v == edge[j - 1].v) continue;
      if (belong[i] != belong[v]) out[belong[i]]++;
    }
  int Min = MAX_INT, t;
  for (int i = 1; i < number; i++) {
    if (out[i] != 0) continue;
    if (getsum[i] < Min) {
      Min = getsum[i];
      t = i;
    }
  }
  printf("%d\n", Min);
  for (int i = 1; i <= n; i++)
    if (belong[i] == t) return i;
}
int main() {
  while (scanf("%d %d %d", &n, &m, &h) != EOF) {
    for (int i = 1; i <= n; i++) scanf("%d", u + i);
    int x, y;
    ecnt = 0;
    memset(head, -1, sizeof(head));
    for (int i = 1; i <= m; i++) {
      scanf("%d %d", &x, &y);
      if ((u[x] + 1) % h == u[y]) addEdge(x, y);
      if ((u[y] + 1) % h == u[x]) addEdge(y, x);
    }
    sort(edge + 1, edge + ecnt + 1, cmp);
    memset(f, 0, sizeof(f));
    for (int i = 1; i <= ecnt; i++)
      if (!f[edge[i].u]) f[edge[i].u] = i;
    f[n + 1] = ecnt + 1;
    for (int i = n; i >= 1; i--)
      if (!f[i]) f[i] = f[i + 1];
    memset(vis, 0, sizeof(vis));
    memset(inst, 0, sizeof(inst));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    number = 1;
    dfstime = 0;
    int tmp = tarjan();
    queue<int> que;
    que.push(tmp);
    memset(vis, 0, sizeof(vis));
    vis[tmp] = 1;
    while (!que.empty()) {
      int x = que.front();
      que.pop();
      printf("%d ", x);
      for (int i = f[x]; i < f[x + 1]; i++) {
        int v = edge[i].v;
        if (!vis[v]) {
          que.push(v);
          vis[v] = 1;
        }
      }
    }
    printf("\n");
  }
  return 0;
}
