#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cassert>
#include<ctime>
#define cmin(a,b) (a>(b)?a=(b),1:0)
#define cmax(a,b) (a<(b)?a=(b),1:0)
#define dmin(a,b) ((a)<(b)?(a):(b))
#define dmax(a,b) ((a)>(b)?(a):(b))
namespace io
{
	int F()
	{
		int n=0,F=1;
		char ch;
		while((ch=getchar())!='-'&&(ch<'0'||ch>'9'));
		ch=='-'?F=0:n=ch-'0';
		while((ch=getchar())>='0'&&ch<='9')n=n*10+ch-'0';
		return F?n:-n;
	}
}
struct edge
{
	int to;
	int next;
}e[333333];
int pe=111111;
void insert(int a,int to)
{
	e[pe]=(edge){to,e[a].next};
	e[a].next=pe++;
}
int a[111111];
int q[111111];
int d[111][111111];
int vis[111111],pv;
int b[111];
int main()
{
	int n=io::F(),m=io::F(),k=io::F(),s=io::F();
	for(register int i=1;i<=n;++i)a[i]=io::F();
	for(register int i=1;i<=m;++i)
	{
		int x=io::F(),y=io::F();
		insert(x,y);
		insert(y,x);
	}
	for(register int i=1;i<=k;++i)
	{
		int hq=1,tq=1;
		++pv;
		for(register int j=1;j<=n;++j)if(a[j]==i)q[tq++]=j,vis[j]=pv;
		for(;hq!=tq;++hq)
			for(int p=e[q[hq]].next;p;p=e[p].next)
				if(vis[e[p].to]!=pv)vis[e[p].to]=pv,q[tq++]=e[p].to,d[i][e[p].to]=d[i][q[hq]]+1;
	}
	for(register int i=1;i<=n;++i)
	{
		for(register int j=1;j<=k;++j)b[j]=d[j][i];
		std::sort(b+1,b+k+1);
		int ans=0;
		for(register int j=1;j<=s;++j)ans+=b[j];
		printf("%d ",ans);
	}
	puts("");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 100005;

vector<int>G[N];
vector<int>vec[105];
int value[N], vis[N], d[N][105], a[105], n, m, k, s;
queue<int>Q;
void solve(int t){
	while(!Q.empty()){
		int u = Q.front(); Q.pop();
		for(int i = 0, v; i < G[u].size(); i ++){
			v = G[u][i];
			if(vis[v] == 0){
				vis[v] = 1;
				d[v][t] = d[u][t] + 1;
				Q.push(v);
			}
		}
	}
}

int main(){
	scanf("%d %d %d %d", &n, &m, &k, &s);
	for(int i = 1; i <= n; i ++){
		scanf("%d", &value[i]);
		vec[value[i]].push_back(i);
	}
	while(m --){
		int u, v;
		scanf("%d %d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	for(int i = 1; i <= k; i ++){
		memset(vis, 0, sizeof(vis));
		for(int j = 0, u; j < vec[i].size(); j ++){
			u = vec[i][j];
			vis[u] = 1;
			Q.push(u);
			d[u][i] = 0;
		}
		solve(i);
	}
	for(int i = 1; i <= n; i ++){
		int c = 0, ans = 0;
		for(int j = 1; j <= k; j ++)a[c ++] = d[i][j];
		sort(a, a + c);
		for(int j = 0; j < s; j ++)ans += a[j];
		printf("%d", ans);
		if(i != n)printf(" ");
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 100005;

vector<int>G[N];
int vis[N], d[105], dis[N], value[N], n, m, k, s;

int solve(int t){
	queue<int> Q;
	Q.push(t);
	memset(d, 0, sizeof(d));
	memset(vis, 0, sizeof(vis));
	int ans = 0, c = 0;
	dis[t] = 0; vis[t] = 1;
	while(!Q.empty()){
		int u = Q.front(); Q.pop();
		if(d[value[u]] == 0){
			d[value[u]] = 1;
			c ++;
			ans += dis[u];
			if(c == s)break;
		}
		for(int i = 0, v; i < G[u].size(); i ++){
			v = G[u][i];
			if(vis[v] == 0){
				vis[v] = 1;
				dis[v] = dis[u] + 1;
				Q.push(v);
			}
		}
	}
	return ans;
}

int main(){
	scanf("%d %d %d %d", &n, &m, &k, &s);
	for(int i = 1; i <= n; i ++)scanf("%d", &value[i]);
	while(m --){
		int u, v;
		scanf("%d %d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	for(int i = 1; i <= n; i ++){
		printf("%d", solve(i));
		if(i != n)printf(" ");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define Max(x,y,z) max(x,max(y,z))
#define Min(x,y,z) min(x,min(y,z))
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define trace1(x)                cerr<<#x<<": "<<x<<endl
#define trace2(x, y)             cerr<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x, y, z)          cerr<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a, b, c, d)       cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define trace5(a, b, c, d, e)    cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define trace6(a, b, c, d, e, f) cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long, long long> pll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef pair<ll,ll> ii;
typedef vector<pair<int,int> > vii;
typedef vector<long long> vll;
typedef vector<vll> vvll;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<pair<long long,long long> > vpll;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef pair<int,pair<int,int> > iii;
#define PI 3.141592653589793
#define mod 998244353
# define N 300005
template<typename T> T gcd(T a,T b) { if(a==0) return b; return gcd(b%a,a); }
template<typename T> T pow(T a,T b, ll m){T ans=1; while(b>0){ if(b%2==1) ans=((ans%m)*(a%m))%m; b/=2; a=((a%m)*(a%m))%m; } return ans%m; }
# define INF (int)1e9
# define LG 20
typedef pair<int,pair<int,int> > pii;
# define INF1 (int)1e9
# define maxn 150005

vector<int>g[maxn],gd[maxn];
bool vis[maxn];
int c[maxn];
vector<int>f[maxn];

int main()
{
	IOS;
	int n,m,s,k;
	cin >> n >> m >> k >> s;
	int u;
	for(int i=1;i<=n;i++)
	{
		cin >> u;
		gd[u].pb(i);
	}
	int x,y;
	for(int i=1;i<=m;i++)
	{
		cin >> x >>y ;
		g[x].pb(y);
		g[y].pb(x);
	}
	for(int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof vis);
		memset(c,0,sizeof c);
		queue<int>q;
		for(int j=0;j<gd[i].size();j++)
		{
			vis[gd[i][j]]=1;
			c[gd[i][j]]=0;
			q.push(gd[i][j]);
		}
		while(!q.empty())
		{
			int node=q.front();
			q.pop();
			for(int j=0;j<g[node].size();j++)
			{
				if(vis[g[node][j]])
					continue;
				vis[g[node][j]]=1;
				c[g[node][j]]=c[node]+1;
				q.push(g[node][j]);
			}
		}
		for(int j=1;j<=n;j++)
		{
			f[j].pb(c[j]);
		}
	}

	for(int i=1;i<=n;i++)
	{
		int ans=0;
		sort(f[i].begin(),f[i].end());
		for(int j=0;j<s;j++)
		{
			//cout << f[i][j]<<" ";
			ans+=f[i][j];
		}
		//cout << "\n";
		cout << ans<<" ";
	}
}


#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int num,fi[N],s[N],d,zz[N],ne[N],n,m,k,x,y,a[N][105],f[N];
queue<int> Q1,Q2;
void jb(int x,int y)
{
	ne[++num]=fi[x];
	fi[x]=num;
	zz[num]=y;
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&d);
	for (int i=1;i<=n;i++)scanf("%d",&s[i]);
	memset(a,10,sizeof a);
	while (m--)
	 {
	 	scanf("%d%d",&x,&y);
	 	jb(x,y);jb(y,x);
	 }
	for (int i=1;i<=k;i++)
	 {
	 	memset(f,0,sizeof f);
	 	for (int j=1;j<=n;j++)
	 	 if (s[j]==i)
	 	  {
	 	  	a[j][i]=0;
	 	  	f[j]=1;
	 	  	Q1.push(j);Q2.push(0);
	 	  }
	 	while (!Q1.empty())
		 {
		 	int now=Q1.front(),nowz=Q2.front();Q2.pop();Q1.pop();
		 	for (int j=fi[now];j;j=ne[j])
		 	 if (!f[zz[j]])
		 	  {
		 	  	f[zz[j]]=1;
		 	  	Q1.push(zz[j]);Q2.push(nowz+1);
		 	  	a[zz[j]][i]=nowz+1;
		 	  }
		 }
	 }
	for (int i=1;i<=n;i++)
	 {
	 	sort(a[i]+1,a[i]+k+1);
	 	int ans=0;
	 	for (int j=1;j<=d;j++)ans+=a[i][j];
	 	printf("%d ",ans);
	 }
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<bitset>
#include<deque>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define ri register int
#define il inline
#define fi first
#define se second
#define mp make_pair
#define pi pair<int,int>
#define mem0(x) memset((x),0,sizeof (x))
#define mem1(x) memset((x),0x3f,sizeof (x))
#define gc getchar
template<class T>void in(T &x)
{
    x = 0; bool f = 0; char c = gc();
    while (c < '0' || c > '9') {if (c == '-') f = 1; c = gc();}
    while ('0' <= c && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = gc();}
    if (f) x = -x;
}
#undef gc
#define N 100010
int u[N << 1], v[N << 1], nx[N << 1], cnt, head[N];
void add(int uu, int vv) {
    u[++cnt] = uu, v[cnt] = vv, nx[cnt] = head[uu];
    head[uu] = cnt;
}
int n, m, k, s;
vector<int>hw[110];
bool vis[N];
int d[N][110];
signed main() {
    in(n), in(m), in(k), in(s);
    for (ri i = 1, t; i <= n; ++i) {
        in(t);
        hw[t].push_back(i);
    }
    for (ri i = 1, uu, vv; i <= m; ++i) {
        in(uu), in(vv);
        add(uu, vv);
        add(vv, uu);
    }
    for (ri i = 1; i <= k; ++i) {
        queue<int>q;
        mem0(vis);
        for (ri j = 0; j < hw[i].size(); ++j) {
            q.push(hw[i][j]);
            vis[hw[i][j]] = 1;
            d[hw[i][j]][i] = 0;
        }
        while (!q.empty()) {
            int x = q.front(); q.pop();
            vis[x] = 1;
            for (ri j = head[x]; j; j = nx[j]) {
                if (vis[v[j]]) continue;
                //if (d[v[j]][i] > d[x][i] + 1) {
                q.push(v[j]);
                d[v[j]][i] = d[x][i] + 1;
                //}
            }
        }
    }
    for (ri i = 1; i <= n; ++i) {
        sort(d[i] + 1, d[i] + 1 + k);
        int ans = 0;
        for (ri j = 1; j <= s; ++j) ans += d[i][j];
        printf("%d\n", ans);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<stack>
#include<bitset>
#include<deque>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define ri register int
#define il inline
#define fi first
#define se second
#define mp make_pair
#define pi pair<int,int>
#define mem0(x) memset((x),0,sizeof (x))
#define mem1(x) memset((x),0x3f,sizeof (x))
#define gc getchar
template<class T>void in(T &x)
{
    x = 0; bool f = 0; char c = gc();
    while (c < '0' || c > '9') {if (c == '-') f = 1; c = gc();}
    while ('0' <= c && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = gc();}
    if (f) x = -x;
}
#undef gc
#define N 100010
int u[N << 1], v[N << 1], nx[N << 1], cnt, head[N];
void add(int uu, int vv) {
    u[++cnt] = uu, v[cnt] = vv, nx[cnt] = head[uu];
    head[uu] = cnt;
}
int n, m, k, s;
vector<int>hw[110];
bool vis[N];
int d[N][110];
signed main() {
    in(n), in(m), in(k), in(s);
    for (ri i = 1, t; i <= n; ++i) {
        in(t);
        hw[t].push_back(i);
    }
    for (ri i = 1, uu, vv; i <= m; ++i) {
        in(uu), in(vv);
        add(uu, vv);
        add(vv, uu);
    }
    for (ri i = 1; i <= k; ++i) {
        queue<int>q;
        mem0(vis);
        for (ri j = 0; j < hw[i].size(); ++j) {
            q.push(hw[i][j]);
            vis[hw[i][j]] = 1;
            d[hw[i][j]][i] = 0;
        }
        while (!q.empty()) {
            int x = q.front(); q.pop();
            vis[x] = 1;
            //if (i == 1) printf("V %d %d\n", x, d[x][i]);
            for (ri j = head[x]; j; j = nx[j]) {
                if (vis[v[j]]) continue;
                //if (d[v[j]][i] > d[x][i] + 1) {
                q.push(v[j]);
                vis[v[j]] = 1;
                //printf("A %d\n", v[j]);
                d[v[j]][i] = d[x][i] + 1;
                //}
            }
        }
    }
    /*for (ri i = 1; i <= k; ++i) {
        for (ri j = 1; j <= n; ++j) {
            printf("%d ", d[j][i]);
        }
        puts("");
    }*/
    for (ri i = 1; i <= n; ++i) {
        sort(d[i] + 1, d[i] + 1 + k);
        int ans = 0;
        for (ri j = 1; j <= s; ++j) ans += d[i][j];
        printf("%d\n", ans);
    }
    return 0;
}


#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>//memset(a, 0, sizeof(a));

#define maxlongint 2147483647
#define ll long long
#define fo(i, x, y) for (int i = x; i <= y; i++)
#define fd(i, x, y) for (int i = x; i >= y; i--)
#define N 500005
using namespace std;
int n,m,k,s;
int tot,to[2*N],la[2*N],ne[2*N];
int a[101][N],x,y;
int d[N],head,tail;
bool p[N];
int b[N][101];
int c[101],ans;
void init() {
	freopen("d.in","r",stdin);
	//freopen("d.out","w",stdout);
}
void link(int u,int v) {
	to[++tot]=v,ne[tot]=la[u],la[u]=tot;
}
int main() {
	//init();
	scanf("%d%d%d%d",&n,&m,&k,&s);
	fo(i,1,n) {
		scanf("%d",&x);
		a[x][++a[x][0]]=i;
	}
	fo(i,1,m) {
		scanf("%d%d",&x,&y);
		link(x,y);
		link(y,x);
	}
	fo(i,1,k) {
		memset(d,0,sizeof(d));
		memset(p,0,sizeof(p));
		head=tail=0;
		fo(j,1,a[i][0]) {
			d[++tail]=a[i][j];
			p[a[i][j]]=1;
		}
		while (++head<=tail) {
			int now=d[head];
			for (int k=la[now];k;k=ne[k]) {
				if (!p[to[k]]) {
					p[to[k]]=1;
					b[to[k]][i]=b[now][i]+1;
					d[++tail]=to[k];
				}
			}
		}
	}
	fo(i,1,n) {
		memset(c,0,sizeof(c));
		fo(j,1,k) c[j]=b[i][j];
		sort(c+1,c+k+1);
		ans=0;
		fo(j,1,s) ans+=c[j];
		printf("%d ",ans);
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;

#define LL long long
#define pa pair<int,int>
#define mp make_pair<int,int>
#define pb push_back
#define pp pop_back
#define reg register
#define prl priority_queue<int,vector<int>,greater<int> >
#define prm priority_queue<int,vector<int>,less<int> >

inline void read(int &x)
{
   x = 0;
   char c = getchar();
   while(c < '0' || c > '9') c = getchar();
   while(c >= '0' && c <= '9')
   {
	 x = x*10 + c - '0';
	 c = getchar();
   }
}

int cnt,m,n,k,s;
int a[1000000],c[2333333],next[2333333],to[2333333];
queue<int> q;

inline void add(reg int u,reg int v)
{
	cnt++;
	to[cnt] = v;
	next[cnt] = c[u];
	c[u] = cnt;
}

int vis[1000001],ans[1000001],city[101][1000001];

inline void bfs(reg int kind)
{
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		for(reg int i = c[x]; i ; i = next[i])
		{
			reg int t = to[i];
			if(vis[t])continue;
			vis[t] = 1;
			city[kind][t] = city[kind][x] + 1;
			q.push(t);
		}
	}
}
int main()
{
	read(n);
	read(m);
	read(k);
	read(s);
	for(reg int i = 1; i <= n; i++)read(a[i]);
    for(reg int i = 1; i <= m; i++)
	{
	  reg int u,v;
	  read(u);
	  read(v);
	  add(u,v);
	  add(v,u);
	}
	memset(city,0x3f3f3f3f,sizeof(city));
	for(reg int i = 1; i <= k; i++)
	{
	   memset(vis,0,sizeof(vis));
	   for(reg int j = 1; j <= n; j++ )
	   {
	      if(a[j] == i)q.push(j),vis[j] = 1,city[i][j] = 0;
	   }
	   bfs(i);
	}
	for(int i = 1; i <= n; i++)
	{
		for(reg int j = 1;j <= k; j++)ans[j] = city[j][i];
		nth_element(ans+1,ans+s+1,ans+k+1);
		reg int d = 0;
		for(int i = 1; i<=s; i++)d += ans[i];
		printf("%d\n",d);
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;

#define LL long long
#define pa pair<int,int>
#define mp make_pair<int,int>
#define pb push_back
#define pp pop_back
#define reg register
#define prl priority_queue<int,vector<int>,greater<int> >
#define prm priority_queue<int,vector<int>,less<int> >

inline void read(int &x)
{
   x = 0;
   char c = getchar();
   while(c < '0' || c > '9') c = getchar();
   while(c >= '0' && c <= '9')
   {
	 x = x*10 + c - '0';
	 c = getchar();
   }
}

int cnt,m,n,k,s;
int a[1000000],c[2333333],next[2333333],to[2333333];
queue<int> q;

inline void add(reg int u,reg int v)
{
	cnt++;
	to[cnt] = v;
	next[cnt] = c[u];
	c[u] = cnt;
}

int vis[1000001],ans[1000001],city[100][1000001];

inline void bfs(reg int kind)
{
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		for(reg int i = c[x]; i ; i = next[i])
		{
			reg int t = to[i];
			if(vis[t])continue;
			vis[t] = 1;
			city[kind][t] = city[kind][x] + 1;
			q.push(t);
		}
	}
}
int main()
{
	read(n);
	read(m);
	read(k);
	read(s);
	for(reg int i = 1; i <= n; i++)read(a[i]);
    for(reg int i = 1; i <= m; i++)
	{
	  reg int u,v;
	  read(u);
	  read(v);
	  add(u,v);
	  add(v,u);
	}
	memset(city,0x3f3f3f3f,sizeof(city));
	for(reg int i = 1; i <= k; i++)
	{
	   memset(vis,0,sizeof(vis));
	   for(reg int j = 1; j <= n; j++ )
	   {
	      if(a[j] == i)q.push(j),vis[j] = 1,city[i][j] = 0;
	   }
	   bfs(i);
	}
	for(int i = 1; i <= n; i++)
	{
		for(reg int j = 1;j <= k; j++)ans[j] = city[j][i];
		nth_element(ans+1,ans+s+1,ans+k+1);
		reg int d = 0;
		for(int i = 1; i<=s; i++)d += ans[i];
		printf("%d\n",d);
	}
	return 0;
}


#include<bits/stdc++.h>
#define N 100005
using namespace std;

inline void read(int &X)
{
    X=0;int w=0;char ch=0;
    while(!isdigit(ch))w|=ch=='-',ch=getchar();
    while( isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    X=w?-X:X;
}

int n,m,k,s;
int a[N],dis[N][105];
int head[N],cnt,num[105];
struct nd{int nxt,to;}e[N<<1];
#define For(x) for(int y,i=head[x];(y=e[i].to);i=e[i].nxt)

void add(int x,int y)
{
  e[++cnt]=(nd){head[x],y};head[x]=cnt;
  e[++cnt]=(nd){head[y],x};head[y]=cnt;
}
void bfs(int pd)
{
  queue<int> q;
  for(int i=1;i<=n;i++)
    if(a[i]==pd) q.push(i),num[pd]++;
  while(!q.empty())
  {
    int x=q.front();q.pop();
    For(x) if(!dis[y][pd] and a[y]!=pd)
      dis[y][pd]=dis[x][pd]+1,q.push(y);
  }
}

int work(int x)
{
  int ans=0;
  sort(dis[x]+1,dis[x]+1+k);
  for(int i=1;i<=s;i++)
    ans+=dis[x][i];
  return ans;
}

signed main()
{
    read(n);read(m);read(k);read(s);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int x,y,i=1;i<=m;i++)
      read(x),read(y),add(x,y);
    for(int i=1;i<=k;i++) bfs(i);
    for(int i=1;i<=n;i++)
      printf("%d ",work(i));
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int s){
	queue<int> Q;
	int sz=Goods[s].size();
    for (int i=0;i<sz;i++){
    	int x=Goods[s][i];
    	Q.push(x);
    	d[s][x]=0;
	}

     while (!Q.empty()){

    	int x=Q.front();
    	Q.pop();
    	for (int i=0;i<G[x].size();i++){
    	    node=G[x][i];
			if( d[s][node] > d[s][x] + 1){
                d[s][node] = d[s][x] + 1;
                Q.push(node);
            }
	 }
}
	  return;

}

int main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]),Goods[a[i]].push_back(i);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0x3f,sizeof(d));
	for (int i=1;i<=k;i++)   solve(i);

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
       cout<<ans<<" ";
    }
    return 0;
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int st)
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==st) //������ĳһ��(ö��k����Ʒ)
        {
            d[st][i]=0;
            q.push(i); //��¼�±�
        }
    }
    while( !q.empty() )
    {
         //ÿ�ε�����ȡ����ͷ�ĵ�u������ö�ٴ�u�����ı�
        int u=q.front();q.pop();
        for(int i=0; i<G[u].size(); i++)
        {
            int v=G[u][i];
            //��dis[v]+1 < dis[v]����Ľ�dis[v]
            if(d[st][v] > d[st][u] + 1)
            {
                d[st][v] = d[st][u] + 1;//û�ж������Ƿ��Ѿ���v,���ܻ���һЩ
                q.push(v); //��ʱ����st��v����̾����С�ˣ��п���v���ԸĽ������ĵ㣬������v���ڶ����У��ͽ��������β
            } //����һֱ������ȥֱ�����б�գ�Ҳ����S�����нڵ����̾��붼ȷ�������������㷨
        }
    }
}

int main(){
	//freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]),Goods[a[i]].push_back(i);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0x3f,sizeof(d));
	for (int i=1;i<=k;i++)   solve(i);

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
       cout<<ans<<' ';
    }
    return 0;
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int st)
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==st) //������ĳһ��(ö��k����Ʒ)
        {
            d[st][i]=0;
            q.push(i); //��¼�±�
        }
    }
    while( !q.empty() )
    {
         //ÿ�ε�����ȡ����ͷ�ĵ�u������ö�ٴ�u�����ı�
        int u=q.front();q.pop();
        for(int i=0; i<G[u].size(); i++)
        {
            int v=G[u][i];
            //��dis[v]+1 < dis[v]����Ľ�dis[v]
            if(d[st][v] > d[st][u] + 1)
            {
                d[st][v] = d[st][u] + 1;//û�ж������Ƿ��Ѿ���v,���ܻ���һЩ
                q.push(v); //��ʱ����st��v����̾����С�ˣ��п���v���ԸĽ������ĵ㣬������v���ڶ����У��ͽ��������β
            } //����һֱ������ȥֱ�����б�գ�Ҳ����S�����нڵ����̾��붼ȷ�������������㷨
        }
    }
}

int main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]),Goods[a[i]].push_back(i);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0x3f,sizeof(d));
	for (int i=1;i<=k;i++)   solve(i);

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
       cout<<ans<<' ';
    }
    return 0;
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int st){
	memset(vis,0,sizeof(vis));
	queue<int> Q;
  for(int i=1;i<=n;i++){
        if(a[i]==st)
        {
            d[st][i]=0;
            Q.push(i);
            vis[i]=true;
        }
    }

     while (!Q.empty()){
    	int x=Q.front();
    	Q.pop();
    	for (int i=0;i<G[x].size();i++){
    	    node=G[x][i];
    	  //  printf("%d ",node);
			if (vis[ node ]) continue;
			d[st][node]=d[st][x]+1;
			Q.push(node);
			vis[node]=true;
	   }
    }
   // printf("\n");

 //  for (int i=1;i<=n;i++) cout<<d[st][i]<<' ';
   // cout<<endl;

}

int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0,sizeof(d));
	for (int j=1;j<=k;j++)   { solve(j);}

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
        cout<<ans<<' ';
    }
    return 0;
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int s){
	queue<int> Q;
	int sz=Goods[s].size();
    for (int i=0;i<sz;i++){
    	int x=Goods[s][i];
    	Q.push(x);
    	d[s][x]=0;
	}

     while (!Q.empty()){

    	int x=Q.front();
    	Q.pop();
    	for (int i=0;i<G[x].size();i++){
    	    node=G[x][i];
			if( d[s][node] > d[s][x] + 1){
                d[s][node] = d[s][x] + 1;
                Q.push(node);
            }
	 }
}
	  return;

}

int main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]),Goods[a[i]].push_back(i);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0x3f,sizeof(d));
	for (int i=1;i<=k;i++)   solve(i);

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
       ccout<<ans<<" ";
    }
    return 0;
}


#include <iostream>
#include<queue>
#include<string.h>
#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define M 2005
const int  INF =  0x3f3f3f3f;
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define ll long long
int n,m,k,s,u,v;
int a[N];
vector<int> G[N];
int d[N];
int dis[105][N];//dist[i]��Դ��i��Ŀǰ���·����

void bfs(int st)
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==st) //������ĳһ��(ö��k����Ʒ)
        {
            dis[st][i]=0;
            q.push(i); //��¼�±�
        }
    }
    while( !q.empty() )
    {
         //ÿ�ε�����ȡ����ͷ�ĵ�u������ö�ٴ�u�����ı�
        int u=q.front();q.pop();
        for(int i=0; i<G[u].size(); i++)
        {
            int v=G[u][i];
            //��dis[v]+1 < dis[v]����Ľ�dis[v]
            if(dis[st][v] > dis[st][u] + 1)
            {
                dis[st][v] = dis[st][u] + 1;//û�ж������Ƿ��Ѿ���v,���ܻ���һЩ
                q.push(v); //��ʱ����st��v����̾����С�ˣ��п���v���ԸĽ������ĵ㣬������v���ڶ����У��ͽ��������β
            } //����һֱ������ȥֱ�����б�գ�Ҳ����S�����нڵ����̾��붼ȷ�������������㷨
        }
    }
}
int main()
{
    memset(dis,120,sizeof(dis));
    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1; i<=k; i++) bfs(i);//��k����ͬ���͵�ö��,����dis���·��
    for(int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) d[j]=dis[j][i];
        sort(d+1,d+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=d[j];
        cout << ans << ' ';
    }
    cout<<endl;
}


#include<bits/stdc++.h>

using namespace std;

const int N=100001;
const int K=101;
int visited[N];
int temp[N][K];
vector<int> graph[N];
int ret[N];
int arr[N];

void bfs(int a,int n)
{
	queue<int> q;
	for(int i=1;i<=n;i++)
	{
		if(arr[i]==a)
		{
			q.push(i);
			visited[i]=1;
		}
	}

	while(!q.empty())
	{
		int z=q.front();
		q.pop();

		for(int i=0;i<graph[z].size();i++)
		{
			if(visited[graph[z][i]]==0)
				{
					visited[graph[z][i]]=1;
					ret[graph[z][i]]=ret[z]+1;
					q.push(graph[z][i]);
				}
		}
	}

	for(int i=1;i<=n;i++)
	{
		temp[i][a]=ret[i];
		ret[i]=0;
		visited[i]=0;
	}
}

int main()
{
	int n,m,k,s;
	cin>>n>>m>>k>>s;
	for(int i=1;i<=n;i++)
		cin>>arr[i];

	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	for(int i=1;i<=k;i++)
		bfs(i,n);

	for(int i=1;i<=n;i++)
	{
		int sum=0;
		sort(temp[i]+1,temp[i]+k+1);
		for(int j=1;j<=s;j++)
			sum+=temp[i][j];
		cout<<sum<<" ";
	}
	cout<<endl;

	return 0;
}


#include "stdio.h"
#include <iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef long long int lld;
int main(){
	int n,m,s,k;
	cin>>n>>m>>k>>s;
	vector<int>goods[k];
	for(int i=0;i<n;i++){
		int x;
		cin>>x;
		x--;
		goods[x].push_back(i);
	}
	vector<int>nei[n];
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		x--;y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	lld dist[n][k];
	for(int i=0;i<k;i++){
		for(int j=0;j<n;j++)dist[j][i]=-1;
		queue<int> q;
		for(int j=0;j<goods[i].size();j++){
			q.push(goods[i][j]);
			dist[goods[i][j]][i]=0;
		}
		while(!q.empty()){
			int v=q.front();q.pop();
			for(int j=0;j<nei[v].size();j++){
				int node=nei[v][j];
				if(dist[node][i]==-1){
					dist[node][i]=dist[v][i]+1;
					q.push(node);
				}
			}
		}
	}
	/*for(int i=0;i<k;i++){
		for(int j=0;j<n;j++)cout<<dist[j][i]<<" ";
		cout<<endl;
	}*/
	for(int i=0;i<n;i++){
		sort(dist[i],dist[i]+k);
		lld ans=0;
		for(int j=0;j<s;j++){
			ans+=dist[i][j];
		}
		cout<<ans<<" ";
	}

	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <ctime>

using namespace std;

const int MAXN = 100005;
const int MAXK = 105;

struct Edge
{
	int to;
	int next;
}edge[MAXN << 1];

int n,m,k,s,id;
int c[MAXN];
int first[MAXN];
int ans[MAXN][MAXK];

bool mark[MAXN];

void addE(int u,int v)
{
	edge[++id] = (Edge){v,first[u]};
	first[u] = id;
}

void bfs(int p)
{
	memset(mark,0,sizeof(mark));
	queue<int> Q;
	for (int i = 1;i <= n;i++)
	{
		if (c[i] == p)
		{
			ans[i][p] = 0;
			Q.push(i);
		}
		else
			ans[i][p] = (1 << 30) - 1;
	}
	while (!Q.empty())
	{
		int now = Q.front();
		Q.pop();
		if (mark[now])
			continue;
		mark[now] = true;
		for (int i = first[now];i;i = edge[i].next)
			if (ans[now][p] + 1 < ans[edge[i].to][p])
			{
				ans[edge[i].to][p] = ans[now][p] + 1;
				Q.push(edge[i].to);
			}
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> m >> k >> s;
	for (int i = 1;i <= n;i++)
		cin >> c[i];
	for (int u,v,i = 1;i <= m;i++)
	{
		cin >> u >> v;
		addE(u,v);
		addE(v,u);
	}
	for (int i = 1;i <= k;i++)
		bfs(i);
	for (int i = 1;i <= n;i++)
	{
		sort(ans[i] + 1,ans[i] + k + 1);
		int Ans = 0;
		for (int j = 1;j <= s;j++)
			Ans += ans[i][j];
		cout << Ans << ' ';
	}
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[505];
int dist[505];

void dijkstra(int x){
     memset(vis,false, sizeof vis);
     memset(dist,1000009, sizeof dist);

     multiset <int > s;
     s.insert(x);
     dist[x] = 0;
     while(!s.empty()){
          int q=*s.begin();
          s.erase(s.begin());

          if(vis[q]==true)continue;

          vis[q] = true;
          for(int i=0;i<adj[q].size();i++){
               if(dist[adj[q][i]] > dist[q]+1){
                  dist[adj[q][i]] = dist[q]+1  ;
                  s.insert(adj[q][i]);
               }
          }

     }

}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    int c[n+1];
    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){
        dijkstra(i);
        vector <pair<int ,int > > v;
        for(int j=1;j<=n;j++){
             v.push_back(make_pair(dist[j], c[j]));
        }
        sort(v.begin(),v.end());
        set <int > k;
        int sum=0;

        for(int j=0;j<n;j++){
             if(k.find(v[j].second)==k.end()){
              //   cout<<v[j].second<<" ";
                  k.insert(v[j].second);
                  sum += v[j].first;
                  if(k.size() == s)break;
             }

        }
  //       cout<<endl;
       cout<<sum<<" ";

    }

}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005] , v[100005];
bool vis[100005];
int dist[100005][102] ;
queue <int > q;
void bfs(int t){

     while(!q.empty()){
          int u= q.front();
          q.pop();

          for(int i=0;i<adj[u].size();i++){
               if(vis[adj[u][i]] == false){
                  vis[adj[u][i]] = true;
                  dist[adj[u][i]][t] = dist[u][t] + 1;
                  q.push(adj[u][i]);
               }
          }
     }
}

int main(){
     int n,m,k,s;
     cin>>n>>m>>k>>s;

     for(int i=1;i<=n;i++){
          int x;
          cin>>x;
          v[x].push_back(i);
          dist[i][x] = 0;
     }

     for(int i=0;i<n;i++){
          int x,y;
          cin>>x>>y;

          adj[x].push_back(y);
          adj[y].push_back(x);
          }
     for(int i=1;i<=k;i++){
          memset(vis , false , sizeof vis);
          for(int j=0;j<v[i].size();j++){
               q.push(v[i][j]);
               vis[v[i][j]] = true;
          }
          bfs(i);
     }

     for(int i=1;i<=n;i++){int cost = 0;
          sort(dist[i] + 1 , dist[i] + 1 + k);
          for(int j=1;j<=s;j++){
               cost += dist[i][j];
          }
          cout<<cost<<" ";
     }
}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005] , v[100005];
bool vis[100005];
int dist[100005][102] ;
queue <int > q;
void bfs(int t){

     while(!q.empty()){
          int u= q.front();
          q.pop();

          for(int i=0;i<adj[u].size();i++){
               if(vis[adj[u][i]] == false){
                  vis[adj[u][i]] = true;
                  dist[adj[u][i]][t] = dist[u][t] + 1;
                  q.push(adj[u][i]);
               }
          }
     }
}

int main(){
     int n,m,k,s;
     cin>>n>>m>>k>>s;

     for(int i=1;i<=n;i++){
          int x;
          cin>>x;
          v[x].push_back(i);
          dist[i][x] = 0;
     }

     for(int i=0;i<m;i++){
          int x,y;
          cin>>x>>y;

          adj[x].push_back(y);
          adj[y].push_back(x);
          }
     for(int i=1;i<=k;i++){
          memset(vis , false , sizeof vis);
          for(int j=0;j<v[i].size();j++){
               q.push(v[i][j]);
               vis[v[i][j]] = true;
          }
          bfs(i);
     }

     for(int i=1;i<=n;i++){int cost = 0;
          sort(dist[i] + 1 , dist[i] + 1 + k);
          for(int j=1;j<=s;j++){
               cost += dist[i][j];
          }
          cout<<cost<<" ";
     }
}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[100005];
int level[100005],c[100005];

int bfs(int x,int s){
     memset(vis,false, sizeof vis);
     memset(level,0, sizeof level );
     vis[x] = true;
     set <int > k;
     queue <int > q;
     q.push(x);
     level[x] = 0;
     k.insert(c[x]);
     int sum=0,num=1;
     int prev = -1,curr = 0;
     while(!q.empty()){
          int p= q.front();
          q.pop();

           prev++;

          for(int i=0;i<adj[p].size();i++){
              if(vis[adj[p][i]] == false)
              { level[adj[p][i]] = level[p] + 1;
              if(k.find(c[adj[p][i]]) == k.end()) {
                   k.insert(c[adj[p][i]]);
                    num++;
                   sum+=prev + 1;}
               q.push(adj[p][i]);
                   vis[adj[p][i]] = true;

                   if(num == s)return sum;
              }
          }

     }

}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){

        cout<<bfs(i , s)<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[100005];
int level[100005],c[100005];

int bfs(int x,int s){
     memset(vis,false, sizeof vis);
     memset(level,0, sizeof level );
     vis[x] = true;
     set <int > k;
     queue <int > q;
     q.push(x);
     level[x] = 0;
     k.insert(c[x]);
     int sum=0,num=1;
     int prev = -1,curr = 0;
     while(!q.empty()){
          int p= q.front();
          q.pop();

           prev++;

          for(int i=0;i<adj[p].size();i++){
              if(vis[adj[p][i]] == false)
              { level[adj[p][i]] = level[p] + 1;
              if(k.find(c[adj[p][i]]) == k.end()) {
                   k.insert(c[adj[p][i]]);
                    num++;
                   sum+=prev + 1;}
               q.push(adj[p][i]);
                   vis[adj[p][i]] = true;

                   if(num == s)return sum;
              }
          }

     }

          return 0;
}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){

        cout<<bfs(i , s)<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[100005];
int level[100005],c[100005];

int bfs(int x,int s){
     memset(vis,false, sizeof vis);
     memset(level,0, sizeof level );
     vis[x] = true;
     set <int > k;
     queue <int > q;
     q.push(x);
     level[x] = 0;
     k.insert(c[x]);
     int sum=0,num=1;
     int prev = -1,curr = 0;
     while(!q.empty()){
          int p= q.front();
          q.pop();

          for(int i=0;i<adj[p].size();i++){
              if(vis[adj[p][i]] == false)
              { level[adj[p][i]] = level[p] + 1;
              if(k.find(c[adj[p][i]]) == k.end()) {
                   k.insert(c[adj[p][i]]);
                    num++;
                   sum+=level[adj[p][i]];
                  // cout<<p<<" ";
              }
               q.push(adj[p][i]);
                   vis[adj[p][i]] = true;

                   if(num == s)return sum;
              }
          }

     }

          return 0;
}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){

        cout<<bfs(i , s)<<" ";
    }
  //  cout<<bfs(2 , s);
}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[100005];
int level[100005],c[100005];

int bfs(int x,int s){
  //   memset(vis,false, sizeof vis);
  //   memset(level,0, sizeof level );
     vis[x] = true;
     set <int > k;
     queue <int > q;
     q.push(x);
     level[x] = 0;
     k.insert(c[x]);
     int sum=0,num=1;
     int prev = -1,curr = 0;
     while(!q.empty()){
          int p= q.front();
          q.pop();

           prev++;

          for(int i=0;i<adj[p].size();i++){
              if(vis[adj[p][i]] == false)
              { level[adj[p][i]] = level[p] + 1;
              if(k.find(c[adj[p][i]]) == k.end()) {
                   k.insert(c[adj[p][i]]);
                    num++;
                   sum+=prev + 1;}
               q.push(adj[p][i]);
                   vis[adj[p][i]] = true;

                   if(num == s)return sum;
              }
          }

     }

}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){

        cout<<bfs(i , s)<<" ";
    }

}


#include <bits/stdc++.h>
using namespace std;
#define sws ios::sync_with_stdio(false); cin.tie(0);cout.tie (NULL)
vector <int> adj[100005];
bool vis[505];
int level[505],c[505];

int bfs(int x,int s){
  //   memset(vis,false, sizeof vis);
  //   memset(level,0, sizeof level );
     vis[x] = true;
     set <int > k;
     queue <int > q;
     q.push(x);
     level[x] = 0;
     k.insert(c[x]);
     int sum=0,num=1;
     int prev = -1,curr = 0;
     while(!q.empty()){
          int p= q.front();
          q.pop();

           prev++;

          for(int i=0;i<adj[p].size();i++){

              { level[adj[p][i]] = level[p] + 1;
              if(k.find(c[adj[p][i]]) == k.end()) {
                   k.insert(c[adj[p][i]]);
                    num++;
                   sum+=prev + 1;}
               q.push(adj[p][i]);

                   if(num == s)return sum;
              }
          }

     }

}

int main(){
    int n,m,k,s;
    cin>>n>>m>>k>>s;

    for(int i=1;i<=n;i++)cin>>c[i];

    for(int i=0;i<m;i++){
        int x,y;
        cin>>x>>y;

        adj[x].push_back(y);
        adj[y].push_back(x);
        }

//        dijkstra(1);
  //      for(int i=1;i<=n;i++)cout<<dist[i]<<" ";
    //   cout<<endl;

    for(int i=1;i<=n;i++){

        cout<<bfs(i , s)<<" ";
    }

}


#include<bits/stdc++.h>
using namespace std;

int n, m, k, s, a, b, towar[100005], odl[100005];
vector<int>graf[100005], blep[100005];
queue<int>q;

void BFS(int v)
{
    q.push(v);
    odl[v]=0;
    while(!q.empty())
    {
        v=q.front();
        q.pop();
        for(int j=0;j<graf[v].size();j++)
        {
            int w=graf[v][j];
            if(odl[w]==0)
            {
                q.push(w);
                odl[w]=odl[v]+1;
            }
        }
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin>>n>>m>>k>>s;
    for(int i=1;i<=n;i++)cin>>towar[i];
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        graf[a].push_back(b);
        graf[b].push_back(a);
    }
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(towar[j]==i)graf[0].push_back(j);
        }
        BFS(0);
        for(int j=1;j<=n;j++)
        {
            blep[j].push_back(odl[j]-1);
            odl[j]=0;
        }
        graf[0].clear();
    }
    for(int i=1;i<=n;i++)
    {
        sort(blep[i].begin(), blep[i].end());
        int wyn=0;
        for(int j=0;j<s;j++)wyn+=blep[i][j];
        cout<<wyn<<' ';
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;

int n,m,s,k;
int ans;

int dis[maxn][110];
int a[maxn];
vector<int> e[maxn],v[maxn];
queue<int>q;
#define pb(x) push_back(x)
int main(){
	scanf("%d %d %d %d",&n,&m,&k,&s);
	for(int i = 1;i <= n; ++i){
		scanf("%d",&a[i]);
		v[a[i]].pb(i);
	}
	for(int i = 1;i <= m; ++i){
		int x,y;
		scanf("%d %d",&x,&y);
		e[x].pb(y);
		e[y].pb(x);
	}
	memset(dis,-1,sizeof(dis));
	for(int i = 1;i <= k; ++i){
		for(int j = 0;j < v[i].size(); ++j){
			int tmp = v[i][j];
			q.push(tmp);
			dis[tmp][i] = 0;
		}
		while(!q.empty()){
			int u = q.front();
			q.pop();
			for(int j = 0;j < e[u].size(); ++j){
				int y = e[u][j];
				if(dis[y][i] == -1){
					dis[y][i] = dis[u][i] + 1;
					q.push(y);
				}
			}
		}
	}
	for(int i = 1;i <= n; ++i){
		ans = 0;
		sort(dis[i]+1,dis[i]+k+1);
		for(int j = 1;j <= s; ++j){
			ans += dis[i][j];
		}
		printf("%d ",ans);
	}
	return 0;
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

#define maxn 100001
using namespace std;

inline int read(){
    int res=0;char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    return res;
}

int fr,to,vis[maxn];
int n,m,fla[maxn],dis[maxn][101],ans[maxn],k,s;
int point[maxn],head[maxn],nxt[maxn],edge[maxn],tot;

void add (int x,int y){
    point[++tot]=y; nxt[tot]=head[x]; head[x]=tot;
    point[++tot]=x; nxt[tot]=head[y]; head[y]=tot;
}

void bfs (int flavor){
    queue<int> q;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        if(fla[i]==flavor)
            vis[i]=1,dis[i][flavor]=0,q.push(i);
    }
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=nxt[i]){
            int v=point[i];
            if(dis[v][flavor]>dis[u][flavor]+1){
                dis[v][flavor]=dis[u][flavor]+1;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}

bool cmp (int a,int b){
    return a<b;
}

void add_up (int num){
    sort(dis[num]+1,dis[num]+1+k,cmp);
    for(int i=1;i<=s;i++)
        ans[num]+=dis[num][i];
    return ;
}

signed main()
{
    n=read(),m=read(),k=read(),s=read();
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=n;i++)   fla[i]=read();
    for(int i=1;i<=m;i++)   fr=read(),to=read(),add(fr,to);
    for(int i=1;i<=k;i++)   bfs(i);
    for(int i=1;i<=n;i++)   add_up(i);
    for(int i=1;i<=n;i++)   printf("%d ",ans[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int MAX = 100005;

inline int read()
{
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}

int Head[MAX], Next[MAX << 1], To[MAX << 1], edgenum = 0;
inline void Add_edge(int from, int to)
	{
		Next[++ edgenum] = Head[from];
		Head[from] = edgenum;
		To[edgenum] = to;
		return ;
	}

queue<int> q;
int dist[MAX][105], vis[MAX];
void BFS(int num)
	{
		for(;!q.empty();)
			{
				int u = q.front(); q.pop();
				for(int i = Head[u]; i != -1; i = Next[i])
					{
						int v = To[i];
						if(!vis[v])
							{
								dist[v][num] = dist[u][num] + 1;
								vis[v] = 1;
								q.push(v);
							}
					}
			}
		return;
	}

vector<int> g[105];
int main()
{
//	freopen("Fair.in", "r", stdin);
	memset(Head, -1, sizeof(Head));
	memset(dist, 0x7f, sizeof(dist));
	int n, m, k, s, x, y, ans;
	scanf("%d%d%d%d", &n, &m, &k, &s);
	for(int i = 1; i <= n; ++ i)
		{
			x = read();
			g[x].push_back(i);
		}
	for(int i = 1; i <= m; ++ i)
		{
			x = read(), y = read();
			Add_edge(x, y);
			Add_edge(y, x);
		}
	for(int i = 1; i <= k; ++ i)
		{
			memset(vis, 0, sizeof(vis));
			for(int j = 0; j < g[i].size(); ++ j)
				{
					dist[g[i][j]][i] = 0;
					vis[g[i][j]] = 1;
					q.push(g[i][j]);
				}
			BFS(i);
		}
	for(int i = 1; i <= n; ++ i)
		{
			ans = 0;
			sort(dist[i] +1, dist[i] +(k + 1));
			for(int j = 1; j <= s; ++ j)	ans += dist[i][j];
			printf("%d ", ans);
		}
	printf("\n");
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXX=100100;
queue<int>q;
vector<int>p[200];
int head[MAXX],ver[MAXX<<1],nxt[MAXX<<1],dis[101][MAXX],a[101];
int n,m,k,s,tot;
bool v[MAXX];
void add(int x,int y){
	ver[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void bfs(){
	for(int e=1;e<=k;++e){
		memset(v,0,sizeof(v));
		for(unsigned int j=0;j<p[e].size();++j){
			q.push(p[e][j]);
			v[p[e][j]]=1;
		}
        while(!q.empty()){
    	int x=q.front();
    	q.pop();
    	v[x]=1;
    	for(int i=head[x];i;i=nxt[i]){
    		int y=ver[i];
    		if(v[y])continue;
            dis[e][y]=dis[e][x]+1;
            q.push(y);
    	}
      }
   }
}
void solve(){
	for(int i=1;i<=n;++i){
		for(int j=1;j<=k;++j){
           a[j]=dis[j][i];
		}
		sort(a+1,a+k+1);
		int ans=0;
        for(int i=1;i<=s;++i)ans+=a[i];
        printf("%d ",ans);
	}
}
int main(){
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;++i){
		int t;
        scanf("%d",&t);
        p[t].push_back(i);
	}
	for(int i=1;i<=m;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	bfs();
	solve();
	return 0;
}


#include<vector>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
const int maxn=1e5+1;
using namespace std;

int n,m,k,s,node;
int a[maxn];
vector<int> G[maxn];
int d[101][maxn];
bool vis[maxn];
vector<int> Goods[101];

void addedge(int from,int to){
    G[from].push_back(to);
    G[to].push_back(from);
}

void solve(int st){
	memset(vis,0,sizeof(vis));
	queue<int> Q;
  for(int i=1;i<=n;i++){
        if(a[i]==st)
        {
            d[st][i]=0;
            Q.push(i);
            vis[i]=true;
        }
    }

     while (!Q.empty()){
    	int x=Q.front();
    	Q.pop();
    	for (int i=0;i<G[x].size();i++){
    	    node=G[x][i];
    	  //  printf("%d ",node);
			if (vis[ node ]) continue;
			d[st][node]=d[st][x]+1;
			Q.push(node);
			vis[node]=true;
	   }
    }
   // printf("\n");

 //  for (int i=1;i<=n;i++) cout<<d[st][i]<<' ';
   // cout<<endl;

}

int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&s);

	for (int i=1;i<=n;i++)
	  scanf("%d",&a[i]);
    int from,to;
	for (int i=1;i<=m;i++){
		scanf("%d%d",&from,&to);
	    addedge(from,to);
	}

	memset(d,0,sizeof(d));
	for (int j=1;j<=k;j++)   { solve(j);}

  int dist[maxn];
  for (int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) dist[j]=d[j][i];
        sort(dist+1,dist+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=dist[j];
        cout<<ans<<' ';
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m,K,S,tot,x,y,k[100100],h[101][100100],dis[100100][101],ans[100100],head[100100],vis[100100];
struct Node{
    int y,nxt;
}side[200100];
void add(int x,int y){
    tot++;
    side[tot].y=y;
    side[tot].nxt=head[x];
    head[x]=tot;
}
void BFS(int t){
    queue<int> q;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=h[t][0];i++)
    q.push(h[t][i]),dis[h[t][i]][t]=0,vis[h[t][i]]=1;
    while(!q.empty()){
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=side[i].nxt){
        	int y=side[i].y;
            if(dis[y][t]>dis[x][t]+1){
            	dis[y][t]=dis[x][t]+1;
            	if(!vis[y]) q.push(y),vis[y]=1;
            }
        }
    }
}
int main(){
    cin>>n>>m>>K>>S;
    for(int i=1;i<=n;i++) cin>>k[i],h[k[i]][++h[k[i]][0]]=i;
    for(int i=1;i<=m;i++)
    cin>>x>>y,add(x,y),add(y,x);
    memset(dis,0x3f,sizeof(dis));
    for(int i=1;i<=K;i++) BFS(i);
    for(int i=1;i<=n;i++){
        sort(dis[i]+1,dis[i]+1+K);
        for(int j=1;j<=S;j++)
        ans[i]+=dis[i][j];
    }
    for(int i=1;i<=n;i++)
    cout<<ans[i]<<" ";
}


#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>

using namespace std;
const int N=100010;

int n,m,k,s;
struct data
{
	int nxt,v;
}edge[N<<1];
int cnt,alist[N];
inline void add(int u,int v)
{
	edge[++cnt]=(data){alist[u],v},alist[u]=cnt;
}
queue<int> q[105];
int dis[N][105],num[N];
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&s);
	memset(dis,0x3f3f3f3f,sizeof dis);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&num[i]);
		q[num[i]].push(i);dis[i][num[i]]=0;
	}
	for(int i=1,x,y;i<=m;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
//	return 0;
	for(int i=1;i<=k;++i)
	{
		while(!q[i].empty())
		{
			int x=q[i].front();q[i].pop();//printf("qqq\n");
			for(int h=alist[x];h;h=edge[h].nxt)
			{
				int v=edge[h].v;
				if(dis[v][i]>dis[x][i]+1) dis[v][i]=dis[x][i]+1,q[i].push(v);
			//	printf("qqq\n");
			}
		}
	}
//	return 0;
	for(int i=1;i<=n;++i)
	{
		int sum=0;
		sort(dis[i]+1,dis[i]+1+k);
		for(int j=1;j<=s;++j) sum+=dis[i][j];
		printf("%d ",sum);
	}
}


#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define N 100005
#define M 105
#define min(A,B) ((A)<(B)?(A):(B))
#define max(A,B) ((A)>(B)?(A):(B))
#define swap(A,B) ((A)^=(B)^=(A)^=(B))

int dis[N];
bool in[N];
int f[N][M];
int type[N];
int head[N];
int n,m,k,s,cnt;
std::queue<int> q;

struct Edge{
    int to,nxt;
}edge[N<<1];

void add(int x,int y){
    edge[++cnt].to=y;
    edge[cnt].nxt=head[x];
    head[x]=cnt;
}

int getint(){
    int x=0,f=0;char ch=getchar();
    while(!isdigit(ch)) f|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return f?-x:x;
}

signed main(){
    n=getint(),m=getint(),k=getint(),s=getint();
    for(int i=1;i<=n;i++)
        type[i]=getint();
    for(int i=1;i<=m;i++){
        int x=getint(),y=getint();
        add(x,y);add(y,x);
    }
    for(int i=1;i<=k;i++){
        memset(dis,0x3f,sizeof dis);
        for(int j=1;j<=n;j++){
            if(type[j]==i)
                q.push(j),dis[j]=0;
        }
        while(q.size()){
            int u=q.front();q.pop();in[u]=0;
            for(int j=head[u];j;j=edge[j].nxt){
                int to=edge[j].to;
                if(dis[to]>dis[u]+1){
                    dis[to]=dis[u]+1;
                    if(!in[to])
                        q.push(to),in[to]=1;
                }
            }
        }
        for(int j=1;j<=n;j++)
            f[j][i]=dis[j];
    }
    for(int i=1;i<=n;i++){
        int ans=0;
        std::sort(f[i]+1,f[i]+1+k);
        for(int j=1;j<=s;j++)
            ans+=f[i][j];
        printf("%d ",ans);
    }
    return 0;
}


#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=2e9;
struct d
{
	int hw,bs,now;
}node;
vector <int> V[100005];
queue <d> Q;
int dis[100005][105],n,m,k,s,bs[100005],ans[105],da;
bool visit[100005][105];
void BFS()
{
	int bs1,hw1,now1;
	while(!Q.empty())
	{
		bs1=Q.front().bs;
		hw1=Q.front().hw;
		now1=Q.front().now;
		Q.pop();
		for(int i=0;i<V[now1].size();i++)
		{
			if(!visit[V[now1][i]][hw1])
			{
				visit[V[now1][i]][hw1]=true;
				dis[V[now1][i]][hw1]=bs1+1;
				node.hw=hw1;
				node.bs=bs1+1;
				node.now=V[now1][i];
				Q.push(node);
			}
		}
	}
	return ;
}
int main()
{
	scanf("%d %d %d %d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=k;j++)
	dis[i][j]=INF;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&bs[i]);
		visit[i][bs[i]]=true;
		dis[i][bs[i]]=0;
	}
	for(int i=1;i<=m;i++)
	{
		int a,b;
		scanf("%d %d",&a,&b);
		V[a].push_back(b);
		V[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		node.hw=bs[i];
		node.now=i;
		node.bs=0;
		Q.push(node);
	}
	BFS();
	for(int i=1;i<=n;i++)
	{
		da=0;
		for(int j=1;j<=k;j++)
		ans[j]=dis[i][j];
		nth_element(ans+1,ans+s+1,ans+k+1);
		for(int j=1;j<=s;j++)
		da+=ans[j];
		printf("%d ",da);
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e5+50;
int dis[N][120];//dis[i][j]是i这个城镇获得j类货物的最短路径；
int ddd[120];
int to[N],nxt[N],head[N],a[N];
int cnt,n,x,y,m,k,s;
long long ans;
inline void add(int x,int y)
{
	cnt++;
	to[cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
}
inline void bfs(int s)
{
	queue <int> q;//省的每次清空了 。
	for(int i=1;i<=n;i++)
		if(a[i]==s)
		{
			dis[i][s]=0;
			q.push(i);
		}
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=nxt[i])
		{
			int t=to[i];
			if(dis[t][s]>dis[x][s]+1)
			{
				dis[t][s]=dis[x][s]+1;
				q.push(t);
			}
		}
	}
}
int main()
{
	memset(dis,0x3f,sizeof(dis));
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	for(int i=1;i<=k;i++)
		bfs(i);
	for(int i=1;i<=n;i++)
	{
		memset(ddd,0,sizeof ddd);
		for(int j=1;j<=k;j++)
			ddd[j]=dis[i][j];//为了好排序；
		sort(ddd+1,ddd+k+1);
		ans=0;
		for(int j=1;j<=s;j++)
			ans+=ddd[j];
		printf("%lld ",ans);
	 }
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int M=100010;
int n,m,k,s,ans;
int dis[M][110],a[M],head[M*2],cnt,vis[M];
struct Edge
{
	int v,nxt;
}e[M*2];
void add(int u,int v)
{
	e[++cnt].nxt=head[u];
	e[cnt].v=v;
	head[u]=cnt;
}
int main()
{
	int aa,bb;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&aa,&bb);
		add(aa,bb);
		add(bb,aa);
	}
	for(int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof(vis));
		queue<int>q;
		for(int j=1;j<=n;j++)
			if(a[j]==i)
				q.push(j),vis[j]=1;
		while(!q.empty())
		{
			int u=q.front();
			q.pop();
			for(int j=head[u];j;j=e[j].nxt)
			{
				int v=e[j].v;
				if(!vis[v])
				{
					dis[v][i]=dis[u][i]+1;
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		int sum=0;
		sort(dis[i]+1,dis[i]+1+k);
		for(int j=1;j<=s;j++)
		{
			sum+=dis[i][j];
		}
		printf("%d ",sum);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

int n, m, k, s;
vector<int> G[100008];
int dist[100008][108];
int a[100008];

int main()
{
	memset(dist, -1, sizeof(dist));
	scanf ("%d %d %d %d", &n, &m, &k, &s);
	for (int i = 1; i <= n; i ++)
	{
		scanf ("%d", &a[i]);
	}
	for (int i = 1; i <= m; i ++)
	{
		int x, y;
		scanf ("%d %d", &x, &y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for (int i = 1;i <= k; i ++)
	{
		queue<int> q;
		for (int j = 1; j <= n; j ++)
		{
			if (a[j] == i)
			{
				dist[j][i] = 0;
				q.push(j);
			}
		}
		while (!q.empty())
		{
			int x = q.front(); q.pop();
			int siz = G[x].size();
			for (unsigned j = 0; j < siz; j ++)
			{
				int k = G[x][j];
				if (dist[k][i] == -1)
				{
					dist[k][i] = dist[x][i] + 1;
					q.push(k);
				}
			}
		}
	}
	for (int i = 1; i <= n; i ++)
	{
		sort(dist[i] + 1, dist[i] + k + 1);
		int ans = 0;
		for (int j = 1; j <= s; j ++)
		{
			ans += dist[i][j];
		}
		printf ("%d", ans);
		if (i != n) printf (" "); else printf ("\n");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n,m,k,s;
int mass[100000];
bool mark[100000];
int dist[100000][100];
vector<int> G[100000];

void bfs(int tovar){
	for(int i = 0;i < n;++i) mark[i] = false;
	queue<int> Q;
	for(int i = 0;i < n;++i){
		if(mass[i] == tovar){
			Q.push(i);
			dist[i][tovar] = 0;
			mark[i] = true;
		}
	}
	while(!Q.empty()){
		int v = Q.front();
		Q.pop();
		for(int i = 0;i < (int)G[v].size();++i){
			if(mark[G[v][i]] == false){
				dist[G[v][i]][tovar] = dist[v][tovar] + 1;
				mark[G[v][i]] = true;
				Q.push(G[v][i]);
			}
		}
	}
}

int main(){
	cin >> n >> m >> k >> s;
	for(int i = 0;i < n;++i){
		int a;
		cin >> a;
		a--;
		mass[i] = a;
	}
	for(int i = 0;i < m;++i){
		int a,b;
		cin >> a >> b;
		a--;
		b--;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	for(int i = 0;i < k;++i){
		bfs(i);
	}
	for(int i = 0;i < n;++i){
		sort(dist[i], dist[i] + k);
	}
	for(int i = 0;i < n;++i){
		int ans = 0;
		for(int j = 0;j < s;++j){
			ans = ans + dist[i][j];
		}
		cout << ans << ' ';
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#define ll long long
#define maxn 100005
#define re register
#define inf 1e9
#define eps 1e-10
using namespace std;

inline int read()
{
	int x=0,w=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();}
	while(c<='9'&&c>='0') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return w==1?x:-x;
}

vector <int> mp[maxn];
vector <int> col[maxn];
int n,m,s,k,d[maxn][105],w[maxn];
bool vis[maxn];
queue <int> que;

inline void bfs(int x)
{
	while(!que.empty())
	{
		int u=que.front(); que.pop();
		for(int i=0;i<mp[u].size();i++)
		{
			int v=mp[u][i];
			if(vis[v]) continue;
			d[v][x]=d[u][x]+1; vis[v]=1;
			que.push(v);
		}
	}
}

int main()
{
	n=read(); m=read(); s=read(); k=read();
	for(int i=1;i<=n;i++) w[i]=read(),col[w[i]].push_back(i);
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		mp[u].push_back(v);
		mp[v].push_back(u);
	}
	for(int i=1;i<=s;i++)
	{
		memset(vis,0,sizeof(vis));
		for(int j=1;j<=n;j++) d[j][i]=inf;
		for(int j=0;j<col[i].size();j++) d[col[i][j]][i]=0,que.push(col[i][j]),vis[col[i][j]]=1;
		bfs(i);
	}
	for(int i=1;i<=n;i++)
	{
		sort(d[i]+1,d[i]+s+1);
		int tmp=0;
		for(int j=1;j<=k;j++) tmp+=d[i][j];
		cout<<tmp<<" ";
	}
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<climits>
#include<vector>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define sint(i) scanf("%d",&i)
#define ss(s) scanf("%s",s)
#define pii pair<int,int>
#define mp(i,j) make_pair(i,j)
#define ll long long
#define MAX 1000000000
#define MOD 1000000007
#define vi vector<int>
#define vvi vector < vi >
#define pb(i) push_back(i);
#define tr(v,it) for(it=v.begin();it!=v.end();it++)
#define DEBUG 0
int main(){
	int n,m,k,s;
	int i,j;
	cin>>n>>m>>k>>s;
	vvi color(k+1,vi());
	int col;
	FOR(i,1,n) {
		cin>>col;
		color[col].pb(i);
	}
	vvi g(n+1,vi());
	int a,b;
	FOR(i,1,m) {
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}
	queue<int> bfs_queue;
	vvi dist(n+1, vi(k+1,0));
	vi::iterator it;
	FOR(i,1,k) {
		vector<bool> visited(n+1,false);
		tr(color[i],it) {
			bfs_queue.push(*it);
			dist[*it][i] =0 ;
			visited[*it] = true;
		}
		while(!bfs_queue.empty()) {
			int curr = bfs_queue.front();
			bfs_queue.pop();
			tr(g[curr],it) {
				int node = *it;
				if(!visited[node]) {
					visited[node] = true;
					dist[node][i] = dist[curr][i] +1;
					bfs_queue.push(node);
				}
			}
		}
	}

	FOR(i,1,n) {
		nth_element(dist[i].begin()+1,dist[i].begin()+s+1,dist[i].end());
		ll ans=0;
		FOR(j,1,s) {
			ans+= dist[i][j];
		}
		cout<<ans<<" ";
	}
	return 0;
}


#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N=100005;
int n,m,s,k,ans;
int dis[N][105],a[N];
vector<int> e[N],v[N];
queue<int>q;
int main(){
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]),v[a[i]].push_back(i);
	for(int i=1;i<=m;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	memset(dis,-1,sizeof dis);
	for(int c=1;c<=k;++c){
		for(int j=0;j<v[c].size();++j){
			int i=v[c][j];
			q.push(i);
			dis[i][c]=0;
		}
		while(!q.empty()){
			int x=q.front();
			q.pop();
			for(int j=0;j<e[x].size();++j){
				int i=e[x][j];
				if(dis[i][c]==-1){
					dis[i][c]=dis[x][c]+1;
					q.push(i);
				}
			}
		}

	}
	int ans;

	for(int i=1;i<=n;++i){
		ans=0;
		sort(dis[i]+1,dis[i]+k+1);
		for(int j=1;j<=s;++j)
		ans+=dis[i][j];
		printf("%d ",ans);
	}

}


#include <bits/stdc++.h>
#include <queue>
#define inf
using namespace std;
int n, m, k, s;
int goods[100000+5], cost[105][100005];
vector <int> a[100000+5];
void Init()
{
	int x, y;
	cin >> n >> m >> k >> s;
	for(int i = 1;i <= n;i++)
	{
		scanf("%d",&goods[i]);
	}
	for(int i = 1;i <= m;i++)
	{
		scanf("%d%d",&x,&y);
		a[x].push_back(y);
		a[y].push_back(x);
	}
}
void Solve()
{
	for(int c = 1;c <= k;c++)
	{
		queue <int> q;

		for(int i = 1;i <= n;i++)
		{
			if(goods[i] == c)
			{
				q.push(i);
				cost[c][i] = 0;
			}
			else cost[c][i] = -1;
		}

		while(!q.empty())
		{
			int p = q.front();
			q.pop();
			//cout << p << endl;
			for(int i = 0;i < a[p].size();i++)
			{
				if(cost[c][a[p][i]] == -1)
				{
					q.push(a[p][i]);
					cost[c][a[p][i]]= cost[c][p] + 1;
				}
			}
		}
	}

	int c[105], sum;
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= k;j++) c[j] = cost[j][i];
		sort(c+1,c+k+1);
		sum = 0;
		for(int j = 1;j <= s;j++)
		{
			sum += c[j];
		}
		printf("%d ",sum);
	}
	cout << endl;
}
int main()
{
	Init();
	Solve();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;
const int N=1e5+8;
int n,m,ecnt,head[N],k,s,dis[N][105],cnt;
struct Edge{int to,nxt;}e[N<<1];
void add(int bg,int ed){e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;}
vector<int>S[105];
void bfs(int x){
	queue<int>q;
	for(int i=0;i<S[x].size();i++)q.push(S[x][i]),dis[S[x][i]][x]=0;
	while(!q.empty()){
//		cout<<1;
		int u=q.front();q.pop();
		for(int i=head[u],v;i;i=e[i].nxt) {
			v=e[i].to;
			if (dis[v][x]>dis[u][x]+1) {dis[v][x]=dis[u][x]+1;q.push(v);}
		}
	}
}
int main() {
	memset(dis,0x3f,sizeof dis);
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1,x;i<=n;i++) {scanf("%d",&x);S[x].push_back(i);}
	for(int i=1,u,v;i<=m;i++){scanf("%d%d",&u,&v);add(u,v);add(v,u);}
	for(int i=1;i<=k;i++)
		bfs(i);
	for(int i=1;i<=n;i++) {
		// int mn=0x3f3f3f3f;
		sort(dis[i]+1,dis[i]+1+n);
		int ans=0;
		for(int j=1;j<=s;j++) ans+=dis[i][j];
		printf("%d ",ans);
	}
}
// 5 5 4 3
// 1 2 4 3 2
// 1 2
// 2 3
//3 4
//4 1
//4 5


#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <queue>
using namespace std;
const int N=1e5+8;
int n,m,ecnt,head[N],k,s,dis[N][105],cnt;
struct Edge{int to,nxt;}e[N<<1];
void add(int bg,int ed){e[++ecnt].to=ed;e[ecnt].nxt=head[bg];head[bg]=ecnt;}
vector<int>S[105];
void bfs(int x){
	queue<int>q;
	for(int i=0;i<S[x].size();i++)q.push(S[x][i]),dis[S[x][i]][x]=0;
	while(!q.empty()){
//		cout<<1;
		int u=q.front();q.pop();
		for(int i=head[u],v;i;i=e[i].nxt) {
			v=e[i].to;
			if (dis[v][x]>dis[u][x]+1) {dis[v][x]=dis[u][x]+1;q.push(v);}
		}
	}
}
int main() {
	memset(dis,0x3f,sizeof dis);
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1,x;i<=n;i++) {scanf("%d",&x);S[x].push_back(i);}
	for(int i=1,u,v;i<=m;i++){scanf("%d%d",&u,&v);add(u,v);add(v,u);}
	for(int i=1;i<=k;i++)
		bfs(i);
	for(int i=1;i<=n;i++) {
		// int mn=0x3f3f3f3f;
		sort(dis[i]+1,dis[i]+1+k);
		int ans=0;
		for(int j=1;j<=s;j++) ans+=dis[i][j];
		printf("%d ",ans);
	}
}
// 5 5 4 3
// 1 2 4 3 2
// 1 2
// 2 3
//3 4
//4 1
//4 5


#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 100100
#define INF 2100000000
struct node {
	int v;
	node *nnext;
} pool[MAXN*4],*h[MAXN*4];
int cnt=-1;
inline int read() {
	int ret=0;
	char c=getchar();
	while(c<'0' || c>'9')c=getchar();
	do {
		ret=ret*10+c-'0';
		c=getchar();
	} while('0'<=c && c<='9');
	return ret;
}
inline void addedge(int u,int v) {
	node *p=&pool[++cnt];
	p->v=v,p->nnext=h[u],h[u]=p;
	node *q=&pool[++cnt];
	q->v=u,q->nnext=h[v],h[v]=q;
}
int n,m,k,s;
int que[MAXN*4];
int type[MAXN];
vector<int> tys[110];
int dis[MAXN][110];
bool vis[MAXN];
inline void bfs(int t) {
	int u,v;
	int head=0,tail=1;
	memset(vis,0,sizeof(vis));
	for(int i=0; i<tys[t].size(); i++) {
		que[tail++]=tys[t][i];
		dis[tys[t][i]][t]=0;
	}
	while(head !=tail) {
		u=que[head];
		head++;
		for(node *p=h[u]; p; p=p->nnext) {
			v=p->v;
			if(!vis[v]) {
				if(dis[v][t] > dis[u][t]+1) {
					dis[v][t]=dis[u][t]+1;
					vis[v]=true;
					que[tail++]=v;
				}
			}
		}
		vis[u]=false;
	}
}
inline bool cmp(int a,int b) {
	return a>b;
}
int ans=0;
int main() {
	int u,v;
	n=read(),m=read(),k=read(),s=read();
	for(int i=1; i<=n; i++) {
		type[i]=read();
		tys[type[i]].push_back(i);
	}
	for(int i=1; i<=m; i++) {
		u=read(),v=read();
		addedge(u,v);
	}
	for(int i=1; i<=100; i++) {
		for(int j=1; j<=n; j++)dis[j][i]=INF;
		if(!tys[i].empty())
			bfs(i);
	}
	for(int i=1; i<=n; i++) {
		sort(dis[i]+1,dis[i]+100+1);
		ans=0;
		for(int j=1; j<=s; j++)
			ans+=dis[i][j];
		printf("%d ",ans);
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cstdlib>
#include <cmath>
#include <cstdio>

using namespace std;

const int lim = 111111;
int g[lim], e[lim];
int t[lim << 2], nex[lim << 2];
int s[lim];
int d[lim], gd[lim];
int dis[lim][101];
int n,m,k,S, r = 0;

void addedge(int aa, int bb){
	t[++r] = bb;
	if (!g[aa])	g[aa]=e[aa] = r;
	else nex[e[aa]] = r, e[aa] = r;
}

int main(){
	scanf("%d%d%d%d", &n, &m, &k, &S);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &gd[i]);
	for (int i = 1; i <= m; ++i){
		int aa, bb;
		scanf("%d%d", &aa, &bb);
		addedge(aa, bb);
		addedge(bb, aa);
	}

	/*
	for (int i = 1; i <= n; ++i){
		int u = g[i];
		while (u){
			printf("%d", t[u]);
			u=nex[u];
		}
		printf("\n");
	}
	*/

	for (int kd = 1; kd <= k; ++kd){
		for (int i = 1; i <= n; ++i){
			dis[i][kd] = n + 1;
			d[i] = n + 1;
		}
		int l = 1, r = 0;
		for (int i = 1; i <= n; ++i)
			if (gd[i] == kd){
				s[++r] = i;
				d[i] = 0;
			}
		while (l <= r){
			for (int u = g[s[l]]; u; u=nex[u]){
				if (d[t[u]] == n + 1){
					d[t[u]] = d[s[l]] + 1;
					s[++r] = t[u];
				}
			}
			++l;
		}
		//for (int i = 1; i<=n; ++i) printf("%d", s[i]); printf("\n");
		for (int i = 1; i <= n; ++i)
			dis[i][kd] = d[i];
	}

	/*
	for (int i =1; i<=n;++i){
		for(int j=1;j<=k;++j)
			printf("%d ", dis[i][j]);
		printf("\n");
	}
	*/

	for (int i = 1; i <= n; ++i){
		sort(dis[i] + 1, dis[i] + k + 1);
		int ans = 0;
		for (int j = 1; j <= S; ++j)
			ans += dis[i][j];
		printf("%d ", ans);
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cstdlib>
#include <cmath>

using namespace std;

const int lim = 111111;
int g[lim], e[lim];
int t[lim << 2], nex[lim << 2];
int s[lim];
int d[lim], gd[lim];
int dis[lim][101];
int n,m,k,S, r = 0;

void addedge(int aa, int bb){
	t[++r] = bb;
	if (!g[aa])	g[aa]=e[aa] = r;
	else nex[e[aa]] = r, e[aa] = r;
}

int main(){
	scanf("%d%d%d%d", &n, &m, &k, &S);
	for (int i = 1; i <= n; ++i)
		scanf("%d", &gd[i]);
	for (int i = 1; i <= m; ++i){
		int aa, bb;
		scanf("%d%d", &aa, &bb);
		addedge(aa, bb);
		addedge(bb, aa);
	}

	/*
	for (int i = 1; i <= n; ++i){
		int u = g[i];
		while (u){
			printf("%d", t[u]);
			u=nex[u];
		}
		printf("\n");
	}
	*/

	for (int kd = 1; kd <= k; ++kd){
		for (int i = 1; i <= n; ++i){
			dis[i][kd] = n + 1;
			d[i] = n + 1;
		}
		int l = 1, r = 0;
		for (int i = 1; i <= n; ++i)
			if (gd[i] == kd){
				s[++r] = i;
				d[i] = 0;
			}
		while (l <= r){
			for (int u = g[s[l]]; u; u=nex[u]){
				if (d[t[u]] == n + 1){
					d[t[u]] = d[s[l]] + 1;
					s[++r] = t[u];
				}
			}
			++l;
		}
		//for (int i = 1; i<=n; ++i) printf("%d", s[i]); printf("\n");
		for (int i = 1; i <= n; ++i)
			dis[i][kd] = d[i];
	}

	/*
	for (int i =1; i<=n;++i){
		for(int j=1;j<=k;++j)
			printf("%d ", dis[i][j]);
		printf("\n");
	}
	*/

	for (int i = 1; i <= n; ++i){
		sort(dis[i] + 1, dis[i] + k + 1);
		int ans = 0;
		for (int j = 1; j <= S; ++j)
			ans += dis[i][j];
		printf("%d ", ans);
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef long long ll;
#define N 100050
int head[N],to[N<<1],nxt[N<<1],cnt,n,m,K,S,w[N],tot,visp[N],Q[N],l,r,visc[N],dep[N];
inline void add(int u,int v) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
ll bfs(int s) {
	ll re=0;
	int i,nowc=1; tot++;
	visp[s]=tot; visc[w[s]]=tot;
	l=r=0; Q[r++]=s; dep[s]=0;if(S==1)return 0;
	while(l<r) {
		int x=Q[l++];
		for(i=head[x];i;i=nxt[i]) {
			if(visp[to[i]]!=tot) {
				visp[to[i]]=tot;
				Q[r++]=to[i]; dep[to[i]]=dep[x]+1;
				if(visc[w[to[i]]]!=tot) {
					visc[w[to[i]]]=tot; re+=dep[to[i]]; nowc++; if(nowc==S) return re;
				}
			}
		}
	}
	return re;
}
int main() {
	scanf("%d%d%d%d",&n,&m,&K,&S);
	int i,x,y;
	for(i=1;i<=n;i++) scanf("%d",&w[i]);
	for(i=1;i<=m;i++) {
		scanf("%d%d",&x,&y); add(x,y); add(y,x);
	}
	for(i=1;i<=n;i++) {
		printf("%lld ",bfs(i));
	}
}


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <iostream>
#include <cstdlib>
using namespace std;
#define N 100005
struct node
{
	int to,next,val;
}e[N<<1];
int head[N],cnt,dis[N],vis[N],a[N],n,m,k,s;
priority_queue <int>ans[N];
void add(int x,int y,int z)
{
	e[cnt].to=y;
	e[cnt].next=head[x];
	e[cnt].val=z;
	head[x]=cnt++;
}
void Dijkstra(int c)
{
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	priority_queue <pair<int ,int> >q;
	while(!q.empty())q.pop();
	for(int i=1;i<=n;i++)
	{
		if(a[i]==c)q.push(make_pair(0,i)),dis[i]=0;
	}
	int num=0;
	while(!q.empty())
	{
		int x=q.top().second;q.pop();
		if(vis[x])continue;
		vis[x]=1;num++;
		if(num==n)break;
		for(int i=head[x];i!=-1;i=e[i].next)
		{
			int to1=e[i].to;
			if(dis[to1]>dis[x]+e[i].val)
			{
				dis[to1]=dis[x]+e[i].val;
				q.push(make_pair(-dis[to1],to1));
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		ans[i].push(-dis[i]);
	}
	return ;
}
int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y,1);add(y,x,1);
	}
	for(int i=1;i<=k;i++)Dijkstra(i);
	for(int i=1;i<=n;i++)
	{
		int sum=0;
		for(int j=1;j<=s;j++)
		{
			sum-=ans[i].top();ans[i].pop();
		}
		printf("%d ",sum);
	}
	puts("");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
typedef long long ll;
#define N 100050
int head[N],to[N<<1],nxt[N<<1],cnt,n,m,K,S,w[N],tot,visp[N],Q[N],l,r,visc[N],dep[N];
inline void add(int u,int v) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
ll bfs(int s) {
	ll re=0;
	int i,nowc=1; tot++;
	visp[s]=tot; visc[w[s]]=tot;
	l=r=0; Q[r++]=s; dep[s]=0;//if(S==1)return 0;
	while(l<r) {
		int x=Q[l++];
		for(i=head[x];i;i=nxt[i]) {
			if(visp[to[i]]!=tot) {
				visp[to[i]]=tot;
				Q[r++]=to[i]; dep[to[i]]=dep[x]+1;
				if(visc[w[to[i]]]!=tot) {
					visc[w[to[i]]]=tot; re+=dep[to[i]]; nowc++; if(nowc==S) return re;
				}
			}
		}
	}
	return re;
}
int main() {

	scanf("%d%d%d%d",&n,&m,&K,&S);
	int i,x,y;
	for(i=1;i<=n;i++) scanf("%d",&w[i]);
	for(i=1;i<=m;i++) {
		scanf("%d%d",&x,&y); add(x,y); add(y,x);
	}
	for(i=1;i<=n;i++) {
		printf("%lld ",bfs(i));
	}
}


#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i )
#define repd(i,x,y) for(register int i = x ; i >= y; -- i )
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
template<typename T>inline void read(T&x)
{
	x = 0;char c;int sign = 1;
	do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
	do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
	x *= sign;
}

const int N = 2e5 + 20;
int n,m,k,s,ans[N][101];
int head[N],nxt[N],to[N],tot;
vector<int>v[N];

inline void add(int x,int y)
{
	to[tot] = y;
	nxt[tot] = head[x];
	head[x] = tot ++;
}

int d[N];
int q[N],st,en;
inline void solve(int c)
{
	st = 1; en = 0;
	memset(d,-1,sizeof d);
	rep(i,0,((int)v[c].size()) - 1)
	{
		d[v[c][i]] = 0;
		q[++en] = v[c][i];
	}

	while(st <= en)
	{
		int x = q[st ++];
		for(register int i = head[x];~i;i=nxt[i])
			if(d[to[i]] == -1)
			{
				d[to[i]] = d[x] + 1;
				q[++en] = to[i];
			}
	}

	rep(i,1,n)
		ans[i][c] = d[i];
}

int main()
{
	memset(head,-1,sizeof head);
	read(n); read(m); read(s); read(k);
	rep(i,1,n)
	{
		int x;
		read(x);
		v[x].push_back(i);
	}

	int u,v;
	rep(i,1,m)
	{
		read(u); read(v);
		add(u,v); add(v,u);
	}

	rep(i,1,s) solve(i);

	rep(i,1,n)
	{
		ll t = 0;
		sort(ans[i] + 1,ans[i] + 1 + s);
		rep(j,1,k) t += ans[i][j];
		printf("%lld ",t);
	}

	return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
const int maxk=105;
const int maxn=(int)1e5+5;
int start[maxn],arr[maxk][maxn];
std::vector<int> g[maxn];
int temp[maxk];
int main() {
	int n,m,s,k;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;++i) scanf("%d",&start[i]);
	int u,v;
	while(m--) {
		scanf("%d%d",&u,&v);
		g[u].push_back(v);g[v].push_back(u);
	}
	for(int i=1;i<=k;++i) {
		memset(arr[i],0x3f,sizeof(arr[i]));std::queue<int> q;
		for(int j=1;j<=n;++j) {
			if(start[j]==i) {
				arr[i][j]=0;
				q.push(j);
			}
		}
		while(q.size()) {
			int x=q.front();q.pop();
			for(int j=0,end=g[x].size();j<end;++j) {
				int y=g[x][j];
				if(arr[i][y]==0x3f3f3f3f) {
					arr[i][y]=arr[i][x]+1;
					q.push(y);
				}
			}
		}
	}
	for(int i=1;i<=n;++i) {
		int ans=0;
		for(int j=1;j<=k;++j) temp[j-1]=arr[j][i];
		std::sort(temp,temp+k);
		for(int j=0;j<s;++j) ans+=temp[j];
		printf("%d ",ans);
	}
	printf("\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
const int maxk=105;
const int maxn=(int)1e5+5;
int start[maxn],arr[maxk][maxn];
std::vector<int> g[maxn];
int temp[maxk];
int main() {
	int n,m,s,k;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;++i) scanf("%d",&start[i]);
	int u,v;
	while(m--) {
		scanf("%d%d",&u,&v);
		g[u].push_back(v);g[v].push_back(u);
	}
	for(int i=1;i<=k;++i) {
		memset(arr[i],0x3f,sizeof(arr[i]));std::queue<int> q;
		for(int j=1;j<=n;++j) {
			if(start[j]==i) {
				arr[i][j]=0;
				q.push(j);
			}
		}
		while(q.size()) {
			int x=q.front();q.pop();
			for(int j=0,end=g[x].size();j<end;++j) {
				int y=g[x][j];
				if(arr[i][y]==0x3f3f3f3f) {
					arr[i][y]=arr[i][x]+1;
					q.push(y);
				}
			}
		}
	}
	for(int i=1;i<=n;++i) {
		int ans=0;
		for(int j=1;j<=k;++j) temp[j-1]=arr[j][i];
		std::sort(temp,temp+k);
		for(int j=0;j<s;++j) ans+=temp[j];
		printf("%d ",ans);
	}
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,k,s,cnt=0;
int col[100100],dis[100100][110];
int head[100100],nxt[100100],to[100100];
int q[1001000],f[100100];
void addedge(int x,int y)
{
	cnt++;
	nxt[cnt]=head[x];
	head[x]=cnt;
	to[cnt]=y;
}
void getdis(int x)
{
	memset(f,0,sizeof(f));
	int l=0,r=0;
	for(int i=1;i<=n;i++)
	{
		if(col[i]==x) q[++r]=i,f[i]=1,dis[i][x]=0;
		else dis[i][x]=10000000;
	}
	while(l<r)
	{
		int u=q[++l];
		for(int i=head[u];i!=-1;i=nxt[i])
		{
			int v=to[i];
			if(dis[v][x]>dis[u][x]+1)
			{
				dis[v][x]=dis[u][x]+1;
				if(!f[v])
				{
					f[v]=1;
					q[++r]=v;
				}
			}
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
		scanf("%d",&col[i]);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	for(int i=1;i<=k;i++)
		getdis(i);
	for(int i=1;i<=n;i++)
	{
		int res=0;
		sort(dis[i]+1,dis[i]+k+1);
		for(int j=1;j<=s;j++)
			res+=dis[i][j];
		cout<<res<<" ";
	}
	return 0;
}


#include<algorithm>
#include<cstring>
#include<cstdio>

struct quere
{
	int a[100020],maxn,l,r;
	quere(int n=100010){maxn=n;l=r=0;}
	void put(int x){a[r=(r+1)%maxn]=x;}
	int get(){return a[l=(l+1)%maxn];}
	bool empty(){return (r+1)%maxn==l;}
	void cls(){l=r=0;}
}lie;

inline int read()
{
	char c;bool f=false;int a=0;
	for (;!((((c=getchar())>='0')&&(c<='9'))||(c=='-')););
	if (c=='-')	f=true;
		else	{a=c-'0';}
	for (;(c=getchar())>='0'&&c<='9';)
	{a=a*10+c-'0';}
	return f?-a:a;
}

int to[800020],next[800020],topl=100020+1;
inline int ljb(int x,int y)
{
	topl++;
	next[topl]=next[x];
	next[x]=topl;
	to[topl]=y;
}

int n,m,k,s,x,y;
int kind[100020];
int vis[100020];
int d[100020][120];

int main()
{
	freopen("test.txt","r",stdin);
	scanf ("%d %d %d %d",&n,&m,&k,&s);
	for (int i=1;i<=n;i++)	kind[i]=read();
	for (int i=1;i<=m;i++)
	{
		x=read();y=read();
		ljb(x,y);
		ljb(y,x);
	}

	memset(d,63,sizeof(d));
	for (int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof(vis));
		lie.cls();
		for (int j=1;j<=n;j++)
		{
			if (kind[j]==i)
			{
				vis[j]=1;
				d[j][i]=0;
				lie.put(j);
			}
		}

		for (int x=lie.get();!lie.empty();x=lie.get())
		{
//			printf ("%d ",x);
			for (int j=next[x];j!=0;j=next[j])
			{
				if (vis[to[j]]==0)
				{
					vis[to[j]]=1;
					d[to[j]][i]=d[x][i]+1;
					lie.put(to[j]);
				}
			}

		}
//		printf ("\n");
	}
	for (int i=1;i<=n;i++)
	{
		int sum=0;
		lie.cls();
		for (int j=1;j<=k;j++)	lie.a[j]=d[i][j];
		std::sort(lie.a+1,lie.a+k+1);
		for (int i=1;i<=s;i++)	sum+=lie.a[i];
		printf ("%d ",sum);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define re register
#define un unsigned
#define rep(i,j,k) for(re un int i = (j); i <= (k); ++i)
#define ll long long
int n,m,k,s;
int a[100005];
bool vis[100005];
int dis[100005][105];
vector<int> road[100005];
queue<int>q;
int main()
{
	scanf("%d %d %d %d",&n,&m,&k,&s);
	rep(i,1,n){
		scanf("%d",&a[i]);
	}
	rep(i,1,n)memset(dis[i],0x3f,sizeof(dis[i]));
	rep(i,1,m){
		int u,v;
		scanf("%d %d",&u,&v);
		road[u].push_back(v);
		road[v].push_back(u);
	}
	rep(i,1,k){
		rep(j,1,n){
			if(a[j] == i){
				q.push(j);vis[j] = 1;
				dis[j][i] = 0;
			}
		}
		while(!q.empty()){
			int cur = q.front();q.pop();vis[cur] = 0;
			for(int j = 0; j < road[cur].size(); ++j){
				int nex = road[cur][j];
				if(dis[nex][i] > dis[cur][i] + 1){
					dis[nex][i] = dis[cur][i] + 1;
					if(!vis[nex]){
						q.push(nex);
						vis[nex] = 1;
					}
				}
			}
		}
	}
	rep(i,1,n){
		sort(dis[i] + 1,dis[i] + 1 + k);
		int ans = 0;
		for(int j = 1; j <= s; ++j){
		    ans += dis[i][j];
		}
		printf("%d ",ans);
	}

}


#include<iostream>
#include<cstdio>
using namespace std;
int a[100005],hed[100005],to[200005],last[200005],p;
bool b[100005];
int f[105][100005],q[100005],t;
void qsort(int x,int y,int k)
{
	int i=x,j=y;
	int mid=f[(x+y)>>1][k];
	do
	{
		while(f[i][k]<mid) i++;
		while(f[j][k]>mid) j--;
		if(i<=j)
		{
			t=f[i][k];
			f[i][k]=f[j][k];
			f[j][k]=t;
			i++;
			j--;
		}
	}while(i<=j);
	if(x<j) qsort(x,j,k);
	if(i<y) qsort(i,y,k);
}
void add(int u,int v)
{
	p++;
	last[p]=hed[u];
	to[p]=v;
	hed[u]=p;
}
int main()
{
	int n,m,s,k,u,v,t1,head,tail;
	cin>>n>>m>>s>>k;
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	for(int i=1;i<=s;i++)
	{
		head=0;
		tail=0;
		for(int j=1;j<=n;j++)
		{
			b[j]=false;
			f[i][j]=0x7ffffff;
		}
		for(int j=1;j<=n;j++)
		if(a[j]==i)
		{
			tail++;
			q[tail]=j;
			f[i][j]=0;
			b[j]=true;
		}
		while(head<tail)
		{
			head++;
			int j=hed[q[head]];
			while(j!=0)
			{
				if(!b[to[j]])
				{
					tail++;
					q[tail]=to[j];
					b[to[j]]=true;
					f[i][to[j]]=f[i][q[head]]+1;
				}
				j=last[j];
			}
		}
	}
	for(int j=1;j<=n;j++)
	{
		qsort(1,s,j);
		t1=0;
		for(int l=1;l<=k;l++)
		t1+=f[j][l];
		cout<<t1<<" ";
	}
	cout<<endl;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>

inline int rd(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
	return x*f;
}

using namespace std;
const int MAXN = 100005;

int n,m,k,s,dis[MAXN][105];
int head[MAXN],cnt;
int to[MAXN<<1],nxt[MAXN<<1];
bool vis[MAXN];
vector<int> g[105];   //g[i]表示第i个货物有哪些能生产，vector大法
queue<int> q;

inline void add(int bg,int ed){
	to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
}

inline void bfs(int kk){
	while(q.size()){
		int x=q.front();q.pop();
		for(register int i=head[x];i;i=nxt[i]){
			int u=to[i];if(vis[u]) continue;
			if(dis[u][kk]>dis[x][kk]+1){
				dis[u][kk]=dis[x][kk]+1;
				vis[u]=1;q.push(u);
			}
		}
	}
}

int main(){
	memset(dis,0x3f,sizeof(dis));
	n=rd();m=rd();k=rd();s=rd();
	int x;
	for(register int i=1;i<=n;i++) x=rd(),g[x].push_back(i);
	for(register int i=1;i<=m;i++){
		int x=rd(),y=rd();
		add(x,y);add(y,x);
	}
	for(register int i=1;i<=k;i++) {
		memset(vis,false,sizeof(vis));
		for(register int j=0;j<g[i].size();j++)
			q.push(g[i][j]),dis[g[i][j]][i]=0,vis[g[i][j]]=1;
		bfs(i);
	}
	for(register int i=1;i<=n;i++){
		sort(dis[i]+1,dis[i]+1+k);
		int ans=0;
		for(register int j=1;j<=s;j++)
			ans+=dis[i][j];
		printf("%d ",ans);
	}
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
vector<int>g[100005];
int n,m,k,s;
int a[100005];
bool vis[100005];
int ans[100005][105];
struct data
{
	int id,d;
};
int bfs(int x,int kind)
{
	memset(vis,0,sizeof(vis));
	queue<data>q;
	while(!q.empty())q.pop();
	data t;t.id=x;t.d=-1;
	q.push(t);
	vis[x]=1;
	while(!q.empty())
	{
		data t=q.front();q.pop();
		int u=t.id,dd=t.d;
		ans[u][kind]=min(ans[u][kind],t.d);
		int ss=g[u].size();
		for(int i=0;i<ss;i++)
		{
			int v=g[u][i];
			if(vis[v]==0)
			{
				vis[v]=1;
				data t2;
				t2.id=v;
				t2.d=t.d+1;
				q.push(t2);
			}
		}
	}

}
bool cmp(int x,int y)
{
	return x<y;
}
int main()
{
	memset(ans,0x3f,sizeof(ans));
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	for(int j=1;j<=k;j++)
	{
		g[0].clear();
		for(int i=1;i<=n;i++)
			if(a[i]==j)g[0].push_back(i);
		bfs(0,j);
	}
	for(int i=1;i<=n;i++)
	{
		int b[105];
		for(int j=1;j<=k;j++)
			b[j]=ans[i][j];
		sort(b+1,b+1+k,cmp);
		int cnt=0;
		for(int j=1;j<=s;j++)cnt+=b[j];
		printf("%d ",cnt);
	}
	return 0;
}


#include<algorithm>
#include<cstring>
#include<cstdio>

struct quere
{
	int a[100020],maxn,l,r;
	quere(int n=100010){maxn=n;l=r=0;}
	void put(int x){a[r=(r+1)%maxn]=x;}
	int get(){return a[l=(l+1)%maxn];}
	bool empty(){return (r+1)%maxn==l;}
	void cls(){l=r=0;}
}lie;

inline int read()
{
	char c;bool f=false;int a=0;
	for (;!((((c=getchar())>='0')&&(c<='9'))||(c=='-')););
	if (c=='-')	f=true;
		else	{a=c-'0';}
	for (;(c=getchar())>='0'&&c<='9';)
	{a=a*10+c-'0';}
	return f?-a:a;
}

int to[800020],next[800020],topl=100020+1;
inline int ljb(int x,int y)
{
	topl++;
	next[topl]=next[x];
	next[x]=topl;
	to[topl]=y;
}

int n,m,k,s,x,y;
int kind[100020];
int vis[100020];
int d[100020][120];

int main()
{
//	freopen("test.txt","r",stdin);
	scanf ("%d %d %d %d",&n,&m,&k,&s);
	for (int i=1;i<=n;i++)	kind[i]=read();
	for (int i=1;i<=m;i++)
	{
		x=read();y=read();
		ljb(x,y);
		ljb(y,x);
	}

	memset(d,63,sizeof(d));
	for (int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof(vis));
		lie.cls();
		for (int j=1;j<=n;j++)
		{
			if (kind[j]==i)
			{
				vis[j]=1;
				d[j][i]=0;
				lie.put(j);
			}
		}

		for (int x=lie.get();!lie.empty();x=lie.get())
		{
//			printf ("%d ",x);
			for (int j=next[x];j!=0;j=next[j])
			{
				if (vis[to[j]]==0)
				{
					vis[to[j]]=1;
					d[to[j]][i]=d[x][i]+1;
					lie.put(to[j]);
				}
			}

		}
//		printf ("\n");
	}
	for (int i=1;i<=n;i++)
	{
		int sum=0;
		lie.cls();
		for (int j=1;j<=k;j++)	lie.a[j]=d[i][j];
		std::sort(lie.a+1,lie.a+k+1);
		for (int i=1;i<=s;i++)	sum+=lie.a[i];
		printf ("%d ",sum);
	}
}


#include <iostream>
#include<queue>
#include<string.h>
#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define M 2005
const int  INF =  0x3f3f3f3f;
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define ll long long
int n,m,k,s,u,v;
int a[N];
vector<int> G[N];
int d[N];
int dis[105][N];//dist[i]是源到i的目前最短路长度

void bfs(int st)
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==st) //起点等于某一类(枚举k个商品)
        {
            dis[st][i]=0;
            q.push(i); //记录下标
        }
    }
    while( !q.empty() )
    {
         //每次迭代，取出队头的点u，依次枚举从u出发的边
        int u=q.front();q.pop();
        for(int i=0; i<G[u].size(); i++)
        {
            int v=G[u][i];
            //若dis[v]+1 < dis[v]，则改进dis[v]
            if(dis[st][v] > dis[st][u] + 1)
            {
                dis[st][v] = dis[st][u] + 1;//没判队列里是否已经有v,可能会慢一些
                q.push(v); //此时由于st到v的最短距离变小了，有可能v可以改进其它的点，所以若v不在队列中，就将它放入队尾
            } //这样一直迭代下去直到队列变空，也就是S到所有节点的最短距离都确定下来，结束算法
        }
    }
}
int main()
{
    memset(dis,120,sizeof(dis));
    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1; i<=k; i++) bfs(i);//从k个不同类型点枚举,保存dis最短路径
    for(int i=1; i<=n; i++)
    {

        for(int j=1; j<=k; j++) d[j]=dis[j][i];
        sort(d+1,d+k+1);
        long long ans=0;
        for(int j=1; j<=s; j++) ans+=d[j];
        cout << ans << ' ';
    }
    cout<<endl;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
struct node
{
	int curr,now;
}no;
int INF=2e9,n,m,k,s,a[100005],step[100005][105];
vector <int> E[100005];
queue <node> Q;
void bfs()
{
	for(int i=1;i<=n;i++)
	{
		no.curr=i;
		no.now=i;
		Q.push(no);
		step[i][a[i]]=0;
	}
	while(!Q.empty())
	{
		int u=Q.front().curr,v=Q.front().now;
		Q.pop();
		for(int i=0;i<E[v].size();i++)
		{
			int t=E[v][i];
			if(step[t][a[u]]==INF)
			{
				no.curr=u;
				no.now=t;
				Q.push(no);
				step[t][a[u]]=step[v][a[u]]+1;
			}
		}
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		E[u].push_back(v);
		E[v].push_back(u);
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=k;j++)
			step[i][j]=INF;
	bfs();
	for(int i=1;i<=n;i++)
	{
		sort(step[i]+1,step[i]+k+1);
		int sum=0;
		for(int j=1;j<=s;j++)
			sum+=step[i][j];
		printf("%d ",sum);
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,k,s,cnt=0;
int col[100100],dis[100100][110];
int head[100100],nxt[100100],to[100100];
int q[1001000];
void addedge(int x,int y)
{
	cnt++;
	nxt[cnt]=head[x];
	head[x]=cnt;
	to[cnt]=y;
}
void getdis(int x)
{
	int l=0,r=0;
	for(int i=1;i<=n;i++)
	{
		if(col[i]==x) q[++r]=i,dis[i][x]=0;
		else dis[i][x]=-1;
	}
	while(l<r)
	{
		int u=q[++l];
		for(int i=head[u];i!=-1;i=nxt[i])
		{
			int v=to[i];
			if(dis[v][x]==-1)
			{
				dis[v][x]=dis[u][x]+1;
				q[++r]=v;
			}
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%d",&n,&m,&k,&s);
	for(int i=1;i<=n;i++)
		scanf("%d",&col[i]);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	for(int i=1;i<=k;i++)
		getdis(i);
	for(int i=1;i<=n;i++)
	{
		int res=0;
		nth_element(dis[i]+1,dis[i]+s+1,dis[i]+k+1);
		for(int j=1;j<=s;j++)
			res+=dis[i][j];
		cout<<res<<" ";
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,m,K,S,cnt,x,y,k[100100],h[101][100100];
int dis[100100][101],ans[100100],alist[100100];
bool vis[100100];
struct data{
	int to,next;
}edge[5005000];
void add(int u,int v)
{
	edge[++cnt].to=v;
	edge[cnt].next=alist[u];
	alist[u]=cnt;
}
queue <int> Q;
void find(int t)
{
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=h[t][0];i++)
    {
    	Q.push(h[t][i]);
		dis[h[t][i]][t]=0;
		vis[h[t][i]]=1;
	}
	while(!Q.empty())
	{
		int now=Q.front();
		Q.pop();
		vis[now]=0;
		for(int i=alist[now];i;i=edge[i].next)
		{
			int too=edge[i].to;
            if(dis[too][t]>dis[now][t]+1)
			{
            	dis[too][t]=dis[now][t]+1;
            	if(!vis[too])
            	{
					Q.push(too);
					vis[too]=1;
				}
            }
		}
	}
}
int main()
{
	cin>>n>>m>>K>>S;
    for(int i=1;i<=n;i++)
		cin>>k[i],h[k[i]][++h[k[i]][0]]=i;
    for(int i=1;i<=m;i++)
    {
    	cin>>x>>y;
		add(x,y);add(y,x);
	}
	memset(dis,0x7f,sizeof(dis));
	for(int i=1;i<=K;i++)
		find(i);

    for(int i=1;i<=n;i++)
	{
        sort(dis[i]+1,dis[i]+1+K);
        for(int j=1;j<=S;j++)
        	ans[i]+=dis[i][j];
    }
    for(int i=1;i<=n;i++)
    	cout<<ans[i]<<" ";
    return 0;
}


#include<algorithm>
#include<cstring>
#include<cstdio>

struct quere
{
	int a[100020],maxn,l,r;
	quere(int n=100010){maxn=n;l=r=0;}
	void put(int x){a[r=(r+1)%maxn]=x;}
	int get(){return a[l=(l+1)%maxn];}
	bool empty(){return (r+1)%maxn==l;}
	void cls(){l=r=0;}
}lie;

int to[800020],next[800020],topl=100020+1;
int ljb(int x,int y)
{
	topl++;
	next[topl]=next[x];
	next[x]=topl;
	to[topl]=y;
}

int n,m,k,s,x,y;
int kind[100020];
int vis[100020];
int d[100020][120];

int main()
{
//	freopen("test.txt","r",stdin);
	scanf ("%d %d %d %d",&n,&m,&k,&s);
	for (int i=1;i<=n;i++)	scanf ("%d",&kind[i]);
	for (int i=1;i<=m;i++)
	{
		scanf ("%d %d",&x,&y);
		ljb(x,y);
		ljb(y,x);
	}

	memset(d,63,sizeof(d));
	for (int i=1;i<=k;i++)
	{
		memset(vis,0,sizeof(vis));
		lie.cls();
		for (int j=1;j<=n;j++)
		{
			if (kind[j]==i)
			{
				vis[j]=1;
				d[j][i]=0;
				lie.put(j);
			}
		}

		for (int x=lie.get();!lie.empty();x=lie.get())
		{
			printf ("%d ",x);
			for (int j=next[x];j!=0;j=next[j])
			{
				if (vis[to[j]]==0)
				{
					vis[to[j]]=1;
					d[to[j]][i]=d[x][i]+1;
					lie.put(to[j]);
				}
			}

		}
		printf ("\n");
	}
	for (int i=1;i<=n;i++)
	{
		lie.cls();
		for (int j=1;j<=k;j++)	lie.put(d[i][j]);
		std::sort(lie.a+1,lie.a+k+1);
		int sum=0;
		for (int i=1;i<=s;i++)	sum+=lie.a[i];
		printf ("%d ",sum);
	}
//	for (;;);
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define LL long long
#define maxn 100005
using namespace std;
int n,m,k,s,cnt,head[maxn],dis[maxn][105],a[maxn],q[maxn];
bool vis[maxn];

inline int rd(){
  int x=0,f=1; char c=' ';
  while(c<'0' || c>'9') {if(c=='-') f=-1;c=getchar();}
  while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
  return x*f;
}

struct EDGE{
  int to,nxt;
}edge[maxn*2];

void add(int x,int y){
  cnt++;
  edge[cnt].to=y;
  edge[cnt].nxt=head[x];
  head[x]=cnt;
}

void bfs(){
  memset(dis,0x3f,sizeof dis);
  for(int now=1;now<=k;now++){
    int h=0,t=0;
    for(int i=1;i<=n;i++){
      if(a[i]==now) q[++t]=i,dis[i][now]=0;
    }
    while(h<t){
      h++; int u=q[h];
      for(int i=head[u];i;i=edge[i].nxt){
        int v=edge[i].to;
        if(dis[v][now]>dis[u][now]+1) q[++t]=v,dis[v][now]=dis[u][now]+1;
      }
    }
  }
}

int main(){
  n=rd(); m=rd(); k=rd(); s=rd();
  for(int i=1;i<=n;i++) a[i]=rd();
  for(int i=1;i<=m;i++){
    int x=rd(),y=rd();
    add(x,y); add(y,x);
  }
  bfs();
  for(int i=1;i<=n;i++){
    LL ans=0;//这地方没开long longWA了一次···
    sort(dis[i]+1,dis[i]+k+1);
    for(int j=1;j<=s;j++) ans+=dis[i][j];
    printf("%lld ",ans);
  }
  return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;
inline int read(){
	int re=0,flag=1;char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-') flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
	return re*flag;
}
int first[101010],cnt=0,n,m,S,K;
int dis[101010][110],vis[101010];
struct edge{
	int to,next;
}a[300010];
inline void add(int u,int v){
	a[++cnt]=(edge){v,first[u]};first[u]=cnt;
	a[++cnt]=(edge){u,first[v]};first[v]=cnt;
}
int q[200010],head,tail,maxq=200000;
void spfa(int s,int num){
	int i,u,v;head=0,tail=1;
	for(i=1;i<=n+K;i++) dis[i][num]=inf,vis[i]=0;
	dis[s][num]=-1;vis[s]=1;q[0]=s;
	while(head!=tail){
		u=q[head];head=(head+1)%maxq;
		for(i=first[u];~i;i=a[i].next){
			v=a[i].to;
			if(dis[v][num]>dis[u][num]+1){
				dis[v][num]=dis[u][num]+1;
				if(!vis[v]){
					vis[v]=1;
					q[tail]=v;tail=(tail+1)%maxq;
				}
			}
		}
	}
}
int main(){
	memset(first,-1,sizeof(first));
	n=read();m=read();K=read();S=read();int i,t1,t2,j;
	for(i=1;i<=n;i++){
		t1=read();
		add(n+t1,i);
	}
	for(i=1;i<=m;i++){
		t1=read();t2=read();
		add(t1,t2);
	}
	for(i=1;i<=K;i++){
		spfa(n+i,i);
	}
	for(i=1;i<=n;i++){
		sort(dis[i]+1,dis[i]+K+1);
		t1=0;
		for(j=1;j<=S;j++) t1+=dis[i][j];
		printf("%d ",t1);
	}
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1e9
#define next ddf
using namespace std;
inline int read(){
	int re=0,flag=1;char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-') flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
	return re*flag;
}
int first[101010],cnt=0,n,m,S,K;
int dis[101010],d[101010][110],vis[101010];
int to[300010],next[300010];
inline void add(int u,int v){
	++cnt;to[cnt]=v;next[cnt]=first[u];first[u]=cnt;
	++cnt;to[cnt]=u;next[cnt]=first[v];first[v]=cnt;
}
int q[200010],head,tail,maxq=200000;
void spfa(int s,int num){
	int i,u,v;head=0,tail=1;
	for(i=1;i<=n+K;i++) dis[i]=inf,vis[i]=0;
	dis[s]=-1;vis[s]=1;q[0]=s;
	while(head!=tail){
		u=q[head];
		head=(head+1)%maxq;
		for(i=first[u];~i;i=next[i]){
			v=to[i];
			if(dis[v]>dis[u]+1){
				dis[v]=dis[u]+1;
				if(!vis[v]){
					vis[v]=1;
					if(dis[v]>dis[q[head]]){
						q[tail]=v;
						tail=(tail+1)%maxq;
					}
					else{
						head=(head-1+maxq)%maxq;
						q[head]=v;
					}
				}
			}
		}
	}
	for(i=1;i<=n;i++) d[i][num]=dis[i];
}
int main(){
	memset(first,-1,sizeof(first));
	n=read();m=read();K=read();S=read();int i,t1,t2,j;
	for(i=1;i<=n;i++){
		t1=read();
		add(n+t1,i);
	}
	for(i=1;i<=m;i++){
		t1=read();t2=read();
		add(t1,t2);
	}
	for(i=1;i<=K;i++){
		spfa(n+i,i);
	}
	for(i=1;i<=n;i++){
		sort(d[i]+1,d[i]+K+1);
		t1=0;
		for(j=1;j<=S;j++) t1+=d[i][j];
		printf("%d ",t1);
	}
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1e9
#define next ddf
using namespace std;
inline int read(){
	int re=0,flag=1;char ch=getchar();
	while(ch>'9'||ch<'0'){
		if(ch=='-') flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
	return re*flag;
}
int first[201010],cnt=0,n,m,S,K;
int dis[201010],d[201010][110],vis[201010];
int to[600010],next[600010];
inline void add(int u,int v){
	++cnt;to[cnt]=v;next[cnt]=first[u];first[u]=cnt;
}
int q[500010],head,tail,maxq=500000;
void spfa(int s,int num){
	int i,u,v;head=0,tail=1;
	for(i=1;i<=n+K;i++) dis[i]=inf,vis[i]=0;
	dis[s]=0;vis[s]=1;q[0]=s;
	while(head!=tail){
		u=q[head];
		head=(head+1)%maxq;
		for(i=first[u];~i;i=next[i]){
			v=to[i];
			if(dis[v]>dis[u]+1){
				dis[v]=dis[u]+1;
				if(!vis[v]){
					vis[v]=1;
					if(dis[v]>dis[q[head]]){
						q[tail]=v;
						tail=(tail+1)%maxq;
					}
					else{
						head=(head-1+maxq)%maxq;
						q[head]=v;
					}
				}
			}
		}
	}
	for(i=1;i<=n;i++) d[i][num]=dis[i];
}
int main(){
	memset(first,-1,sizeof(first));
	n=read();m=read();K=read();S=read();int i,t1,t2,j;
	for(i=1;i<=n;i++){
		t1=read();
		add(n+t1,i);
	}
	for(i=1;i<=m;i++){
		t1=read();t2=read();
		add(t1,t2);add(t2,t1);
	}
	for(i=1;i<=K;i++){
		spfa(n+i,i);
	}
	for(i=1;i<=n;i++){
		sort(d[i]+1,d[i]+K+1);
		t1=0;
		for(j=1;j<=S;j++) t1+=d[i][j];
		printf("%d ",t1-S);
	}
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1e9
#define next ddf
using namespace std;
inline int read(){
    int re=0,flag=1;char ch=getchar();
    while(ch>'9'||ch<'0'){
        if(ch=='-') flag=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    return re*flag;
}
int first[201010],cnt=0,n,m,S,K;
int dis[201010],d[201010][110],vis[201010];
int to[600010],next[600010];
inline void add(int u,int v){
    ++cnt;to[cnt]=v;next[cnt]=first[u];first[u]=cnt;
}
int q[500010],head,tail,maxq=500000;
void spfa(int s,int num){
    int i,u,v;head=0,tail=1;
    for(i=1;i<=n+K;i++) dis[i]=inf,vis[i]=0;
    dis[s]=0;vis[s]=1;q[0]=s;
    while(head!=tail){
        u=q[head];
        head=(head+1)%maxq;
        for(i=first[u];~i;i=next[i]){
            v=to[i];
            if(dis[v]>dis[u]+1){
                dis[v]=dis[u]+1;
                if(!vis[v]){
                    vis[v]=1;
                    if(dis[v]>dis[q[head]]){
                        q[tail]=v;
                        tail=(tail+1)%maxq;
                    }
                    else{
                        head=(head-1+maxq)%maxq;
                        q[head]=v;
                    }
                }
            }
        }
    }
    for(i=1;i<=n;i++) d[i][num]=dis[i];
}
int main(){
    memset(first,-1,sizeof(first));
    n=read();m=read();K=read();S=read();int i,t1,t2,j;
    for(i=1;i<=n;i++){
        t1=read();
        add(n+t1,i);
    }
    for(i=1;i<=m;i++){
        t1=read();t2=read();
        add(t1,t2);add(t2,t1);
    }
    for(i=1;i<=K;i++){
        spfa(n+i,i);
    }
    for(i=1;i<=n;i++){
        sort(d[i]+1,d[i]+K+1);
        t1=0;
        for(j=1;j<=S;j++) t1+=d[i][j];
        printf("%d ",t1-S);
    }
}