#include <bits/stdc++.h>
using namespace std;
const long long maxn = 2e5;
const long long INF = 0x3f3f3f3f;
int a[maxn], k, s;
vector<long long> g[maxn];
struct Edge {
  int from, to;
  long long dist;
  Edge(int u, int v, long long d) : from(u), to(v), dist(d) {}
};
struct Dijkstra {
  int n, m;
  vector<Edge> edges;
  vector<int> G[maxn];
  long long d[maxn];
  void init(int n) { this->n = n; }
  void addEdge(int u, int v) { G[u].push_back(v); }
  void dijkstra(int s) {
    queue<int> Q;
    memset(d, -1, sizeof(d));
    for (int& v : G[s]) {
      d[v] = 0;
      Q.push(v);
    }
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      for (int& v : G[u]) {
        if (d[v] == -1) {
          d[v] = d[u] + 1;
          Q.push(v);
        }
      }
    }
  }
} ans;
int main() {
  int n, m;
  scanf("%d%d%d%d", &n, &m, &k, &s);
  ans.init(n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    ans.addEdge(a[i] + n, i);
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    ans.addEdge(a, b);
    ans.addEdge(b, a);
  }
  for (int i = 1; i <= k; i++) {
    ans.dijkstra(n + i);
    for (int j = 1; j <= n; j++) {
      g[j].push_back(ans.d[j]);
    }
  }
  for (int i = 1; i <= n; i++) {
    sort(g[i].begin(), g[i].end());
    long long ans = 0;
    for (int j = 0; j < s; j++) ans += g[i][j];
    printf("%d ", ans);
  }
}
