#include <bits/stdc++.h>
#pragma GCC optimize("O3")
template <class _Tp>
inline _Tp abs(const _Tp &x) {
  return x < 0 ? -x : x;
}
template <class _Tp>
inline _Tp max(const _Tp &a, const _Tp &b) {
  return a > b ? a : b;
}
template <class _Tp>
inline _Tp min(const _Tp &a, const _Tp &b) {
  return a < b ? a : b;
}
template <class _Tp>
inline void inc(_Tp &a, const _Tp &b) {
  if (a < b) a = b;
}
template <class _Tp>
inline void dec(_Tp &a, const _Tp &b) {
  if (a > b) a = b;
}
template <class _Tp>
inline void swp(_Tp &a, _Tp &b) {
  _Tp c = a;
  a = b;
  b = c;
}
template <class _Tp>
inline bool operator==(const _Tp &A, const _Tp &B) {
  return !memcmp(&A, &B, sizeof(_Tp));
}
using namespace std;
vector<int> G[100005];
int dis[105][100005], n, m, k, s;
int d2[100005][105];
int C[100005];
void bfs(int c) {
  int Q[100005], l = 0, r = -1;
  memset(dis[c], -1, sizeof(dis[c]));
  for (int i = 1; i <= n; ++i)
    if (C[i] == c) Q[++r] = i, dis[c][i] = 0;
  while (l <= r) {
    int u = Q[l++];
    for (auto &v : G[u]) {
      if (!~dis[c][v]) {
        Q[++r] = v;
        dis[c][v] = dis[c][u] + 1;
      }
    }
  }
}
int main() {
  scanf("%d%d%d%d", &n, &m, &k, &s);
  for (int i = 1; i <= n; ++i) scanf("%d", C + i);
  for (int i = 1, x, y; i <= m; ++i) {
    scanf("%d%d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
  for (int i = 1; i <= k; ++i) bfs(i);
  for (int i = 1; i <= k; ++i)
    for (int j = 1; j <= n; ++j) d2[j][i] = dis[i][j];
  for (int j = 1; j <= n; ++j) {
    long long ans = 0;
    std::sort(d2[j] + 1, d2[j] + 1 + k);
    for (int i = 1; i <= s; ++i) ans += d2[j][i];
    printf("%lld ", ans);
  }
  return 0;
}
