#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const long long infLL = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 100000 + 5;
const int maxe = 200000 + 5;
const int maxk = 100 + 5;
int psz;
struct Edge {
  int v;
  Edge *next;
} pool[maxe], *e[maxn];
void add_edge(int u, int v) {
  Edge *i = pool + psz++;
  i->v = v, i->next = e[u];
  e[u] = i;
}
int n, m, k, s;
int a[maxk];
int dis[maxn][maxk];
queue<int> que[maxk];
int main(int argc, char *argv[]) {
  memset(dis, 0x3f, sizeof(dis));
  scanf("%d%d%d%d", &n, &m, &k, &s);
  for (int u = 0; u < (n); ++u) {
    int j;
    scanf("%d", &j);
    --j;
    dis[u][j] = 0, que[j].push(u);
  }
  while (m--) {
    int u, v;
    scanf("%d%d", &u, &v);
    --u, --v;
    add_edge(u, v);
    add_edge(v, u);
  }
  for (int j = 0; j < (k); ++j) {
    while (!que[j].empty()) {
      int u = que[j].front();
      que[j].pop();
      for (Edge *i = e[u]; i; i = i->next) {
        int v = i->v;
        if (dis[u][j] + 1 < dis[v][j]) {
          dis[v][j] = dis[u][j] + 1;
          que[j].push(v);
        }
      }
    }
  }
  for (int u = 0; u < (n); ++u) {
    int ret = 0;
    nth_element(dis[u], dis[u] + s, dis[u] + k);
    for (int i = 0; i < (s); ++i) ret += dis[u][i];
    printf("%d%c", ret, " \n"[u == n - 1]);
  }
  return 0;
}
