#include <bits/stdc++.h>
using namespace std;
template <class T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <typename T>
void debug(T first) {
  cout << first << "\n";
}
template <typename T, typename... Args>
void debug(T first, Args... args) {
  cout << first << " ";
  debug(args...);
}
long long read_ll() {
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-') c = getchar();
  long long ret = 0;
  int neg = 0;
  if (c == '-') neg = 1, c = getchar();
  while (c >= '0' && c <= '9') {
    ret = 10 * ret + c - 48;
    c = getchar();
  }
  return neg ? -ret : ret;
}
const int INF = (long long)(1e8);
const int K = 101;
struct node {
  vector<int> closest;
  int v;
  node(int val) : v(val) {}
};
const int N = (int)1e5 + 5;
int n, m, k, s;
vector<int> g[N];
bool visited[N];
int dist[N];
vector<int> A(N);
vector<vector<int> > nodeWhoHave(K, vector<int>(0));
int closest[N][K];
void dfs(int u, int type) {
  queue<int> q;
  q.push(u);
  while (!q.empty()) {
    auto u = q.front();
    q.pop();
    for (auto v : g[u]) {
      if (visited[v]) continue;
      visited[v] = true;
      dist[v] = dist[u] + 1;
      if (type == A[v])
        closest[v][type] = 0;
      else
        closest[v][type] = min(closest[v][type], dist[v]);
      q.push(v);
    }
  }
}
int main() {
  cin >> n >> m >> k >> s;
  for (int i = 1; i <= n; i++) {
    cin >> A[i];
    nodeWhoHave[A[i]].push_back(i);
  }
  int u, v;
  memset(closest, 0, sizeof(closest));
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= k; j++) closest[i][j] = -1;
  }
  for (int i = 1; i <= m; i++) {
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int kk = 1; kk <= k; kk++) {
    queue<int> q;
    for (auto u : nodeWhoHave[kk]) {
      closest[u][kk] = 0;
      q.push(u);
    }
    while (!q.empty()) {
      auto front = q.front();
      q.pop();
      for (auto v : g[front]) {
        if (closest[v][kk] != -1) continue;
        closest[v][kk] = closest[front][kk] + 1;
        q.push(v);
      }
    }
  }
  vector<int> ans(n + 1);
  for (int i = 1; i <= n; i++) {
    long long sum = 0;
    vector<int> soln(k);
    for (int j = 1; j <= k; j++) {
      soln[j - 1] = closest[i][j];
    }
    sort(soln.begin(), soln.end());
    for (int j = 0; j <= s - 1; j++) sum += soln[j];
    ans[i] = sum;
  }
  for (int i = 1; i <= n; i++) cout << ans[i] << " ";
  return 0;
}
