#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, m, k, s;
  cin >> n >> m >> k >> s;
  vector<int> types(n + 1);
  vector<vector<int>> graph(n + 1);
  vector<vector<int>> type_to_v(k + 1);
  for (int i = 1; i <= n; i++) {
    cin >> types[i];
    type_to_v[types[i]].push_back(i);
  }
  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  auto maxm = numeric_limits<int64_t>::max();
  vector<vector<int64_t>> cost(n + 1, vector<int64_t>(k + 1, maxm));
  for (int i = 1; i <= k; ++i) {
    vector<int> q;
    for (int j = 0; j < type_to_v[i].size(); ++j) {
      int v = type_to_v[i][j];
      q.push_back(v);
      cost[v][i] = 0;
    }
    for (int j = 0; j < q.size(); ++j) {
      int x = q[j];
      for (int l = 0; l < graph[x].size(); ++l) {
        int child = graph[x][l];
        if (cost[child][i] != maxm) continue;
        cost[child][i] = cost[x][i] + 1;
        q.push_back(child);
      }
    }
  }
  vector<int> answers(k);
  for (int v = 1; v <= n; ++v) {
    for (int j = 1; j <= k; ++j) answers[j - 1] = cost[v][j];
    nth_element(answers.begin(), answers.begin() + s, answers.end());
    auto ans = accumulate(answers.begin(), answers.begin() + s, 0);
    cout << ans << " ";
  }
  return 0;
}
