#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 666666
int arr[N];
int low[N],dfn[N],cnt;
int vis[N],used[N];
int f[N];
int num[N],color[N];
vector<int> v[N];
int sig;
int mark[N];
stack<int> s;
void paint(int x){
	s.pop();
	vis[x]=0;
	num[sig]++;
	color[x]=sig;
}
void tarjan(int x){
	low[x]=dfn[x]=++cnt;
	vis[x]=used[x]=1;
	s.push(x);
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(!dfn[to]){
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}else if(vis[to]){
			low[x]=min(low[x],dfn[to]);
		}
	}
	if(dfn[x]==low[x]){
		sig++;
		while(s.top()!=x){
			int t=s.top();
			paint(t);
		}
		paint(x);
		if(num[sig]>1)
			mark[x]=1;
	}
}
int getf(int v){
	if(v==f[v]){
		return f[v];
	}else{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge (int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[t1]=t2;
		num[t2]+=num[t1];
		mark[t2]|=mark[t1];
	}
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		v[a].push_back(b);
	}
	sig=0;
	for(int i=1;i<=n;i++)
		if(!used[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			int t1=color[i];
			int t2=color[v[i][j]];
			merge(t1,t2);
		}
	}
	int ans=0;
	for(int i=1;i<=sig;i++){
		if(f[i]==i){
			if(mark[i]) ans+=num[i];
			else ans+=num[i]-1;
		}
	}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 666666
int arr[N];
int low[N],dfn[N],cnt;
int vis[N],used[N];
int f[N];
int num[N],color[N];
vector<int> v[N];
int sig;
int mark[N];
stack<int> s;
void paint(int x){
	s.pop();
	vis[x]=0;
	num[sig]++;
	if(num[sig]>1)
		mark[x]=1;
	color[x]=sig;
}
void tarjan(int x){
	low[x]=dfn[x]=++cnt;
	vis[x]=used[x]=1;
	s.push(x);
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(!dfn[to]){
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}else if(vis[to]){
			low[x]=min(low[x],dfn[to]);
		}
	}
	if(dfn[x]==low[x]){
		sig++;
		while(s.top()!=x){
			int t=s.top();
			paint(t);
		}
		paint(x);

	}
}
int getf(int v){
	if(v==f[v]){
		return f[v];
	}else{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge (int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[max(t1,t2)]=min(t1,t2);
		num[min(t1,t2)]+=num[max(t1,t2)];
		mark[min(t1,t2)]|=mark[max(t1,t2)];
	}
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		v[a].push_back(b);
	}
	sig=0;
	for(int i=1;i<=n;i++)
		if(!used[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			int t1=color[i];
			int t2=color[v[i][j]];
			merge(t1,t2);
		}
	}
	int ans=0;
	for(int i=1;i<=sig;i++){
		if(f[i]==i){
			if(mark[i]) ans+=num[i];
			else ans+=num[i]-1;
		}
	}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 666666
int arr[N];
int low[N],dfn[N],cnt;
int vis[N],used[N];
int f[N];
int num[N],color[N];
vector<int> v[N];
int sig;
int mark[N];
stack<int> s;
void paint(int x){
	s.pop();
	vis[x]=0;
	num[sig]++;
	color[x]=sig;
}
void tarjan(int x){
	low[x]=dfn[x]=++cnt;
	vis[x]=used[x]=1;
	s.push(x);
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(!dfn[to]){
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}else if(vis[to]){
			low[x]=min(low[x],dfn[to]);
		}
	}
	if(dfn[x]==low[x]){
		sig++;
		while(s.top()!=x){
			int t=s.top();
			paint(t);
		}
		paint(x);
		if(num[sig]>1)
			mark[x]=1;
	}
}
int getf(int v){
	if(v==f[v]){
		return f[v];
	}else{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge (int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[max(t1,t2)]=min(t1,t2);
		num[min(t1,t2)]+=num[max(t1,t2)];
		mark[min(t1,t2)]|=mark[max(t1,t2)];
	}
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		v[a].push_back(b);
	}
	sig=0;
	for(int i=1;i<=n;i++)
		if(!used[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			int t1=color[i];
			int t2=color[v[i][j]];
			merge(t1,t2);
		}
	}
	int ans=0;
	for(int i=1;i<=sig;i++){
		if(f[i]==i){
			if(mark[i]) ans+=num[i];
			else ans+=num[i]-1;
		}
	}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 666666
int arr[N];
int low[N],dfn[N],cnt;
int vis[N],used[N];
int f[N];
int num[N],color[N];
vector<int> v[N];
int sig;
int mark[N];
stack<int> s;
void paint(int x){
	s.pop();
	vis[x]=0;
	num[sig]++;
	if(num[sig]>1)
		mark[sig]=1;
	color[x]=sig;
}
void tarjan(int x){
	low[x]=dfn[x]=++cnt;
	vis[x]=used[x]=1;
	s.push(x);
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(!dfn[to]){
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}else if(vis[to]){
			low[x]=min(low[x],dfn[to]);
		}
	}
	if(dfn[x]==low[x]){
		sig++;
		while(s.top()!=x){
			int t=s.top();
			paint(t);
		}
		paint(x);

	}
}
int getf(int v){
	if(v==f[v]){
		return f[v];
	}else{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge (int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[max(t1,t2)]=min(t1,t2);
		num[min(t1,t2)]+=num[max(t1,t2)];
		mark[min(t1,t2)]|=mark[max(t1,t2)];
	}
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		v[a].push_back(b);
	}
	sig=0;
	for(int i=1;i<=n;i++)
		if(!used[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			int t1=color[i];
			int t2=color[v[i][j]];
			merge(t1,t2);
		}
	}
	int ans=0;
	for(int i=1;i<=sig;i++){
		if(f[i]==i){
			if(mark[i]) ans+=num[i];
			else ans+=num[i]-1;
		}
	}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 666666
int arr[N];
int low[N],dfn[N],cnt;
int vis[N],used[N];
int f[N];
int num[N],color[N];
vector<int> v[N];
int sig;
int mark[N];
stack<int> s;
void paint(int x){
	s.pop();
	vis[x]=0;
	num[sig]++;
	if(num[sig]>1)
		mark[x]=1;
	color[x]=sig;
}
void tarjan(int x){
	low[x]=dfn[x]=++cnt;
	vis[x]=used[x]=1;
	s.push(x);
	for(int i=0;i<v[x].size();i++){
		int to=v[x][i];
		if(!dfn[to]){
			tarjan(to);
			low[x]=min(low[x],low[to]);
		}else if(vis[to]){
			low[x]=min(low[x],dfn[to]);
		}
	}
	if(dfn[x]==low[x]){
		sig++;
		while(s.top()!=x){
			int t=s.top();
			paint(t);
		}
		paint(x);
		if(num[sig]>1)
			mark[x]=1;
	}
}
int getf(int v){
	if(v==f[v]){
		return f[v];
	}else{
		f[v]=getf(f[v]);
		return f[v];
	}
}
void merge (int u,int v){
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2){
		f[max(t1,t2)]=min(t1,t2);
		num[min(t1,t2)]+=num[max(t1,t2)];
		mark[min(t1,t2)]|=mark[max(t1,t2)];
	}
}
signed main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		v[a].push_back(b);
	}
	sig=0;
	for(int i=1;i<=n;i++)
		if(!used[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			int t1=color[i];
			int t2=color[v[i][j]];
			merge(t1,t2);
		}
	}
	int ans=0;
	for(int i=1;i<=sig;i++){
		if(f[i]==i){
			if(mark[i]) ans+=num[i];
			else ans+=num[i]-1;
		}
	}
	cout<<ans<<'\n';
	return 0;
}


                    #include <bits/stdc++.h>

                    typedef long long ll;
                    typedef long double ld;
                    #define rep(i,a,n) for(ll i=(a); i<(n); i++)
                    #define per(i,a,n) for(ll i=(n-1); i>=(a); i--)
                    #define F first
                    #define S second
                    #define maxx(a,b) a=max(a,b)
                    #define minn(a,b) a=min(a,b)
                    #define db(x) cerr<<#x<<" = "<<x<<endl
                    #define N 1111111
                    #define inf 1234567890123456789
                    #define mod 1000000007
                    #define rt return

                    using namespace std;

                    vector<ll> g1[N],g2[N],g[N],ts,cmp,kottacmp;
                    ll n,m,price[N],used1[N],used[N],used2[N];

                    void dfs1(ll v)
                    {
                        used1[v]=1;
                        for(auto x: g1[v])
                            if(!used1[x])dfs1(x);
                        ts.push_back(v);
                    }

                    void dfs2(ll v)
                    {
                        used2[v]=1;
                        cmp.push_back(v);
                        for(auto x: g2[v])
                            if(!used2[x])dfs2(x);
                    }

                    void dfschik(int v)
                    {
                        used[v]=1;
                        kottacmp.push_back(v);
                        for(auto x: g[v])
                            if(!used[x])dfschik(x);
                    }

                    int main()
                    {
                    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

                    cin>>n;
                    cin>>m;

                    rep(i,0,m)
                    {
                        ll j,k; cin>>j>>k;
                        g1[j].push_back(k);
                        g2[k].push_back(j);
                        g[j].push_back(k);
                        g[k].push_back(j);
                    }

                    ll ans=0;

                    rep(q,1,n+1)
                    {
                        if(g[q].empty())continue;
                        if(!used[q])dfschik(q);
                        else continue;

                        for(auto x: kottacmp)
                        if(!used1[x])dfs1(x);

                        reverse(ts.begin(),ts.end());

                        ll kmp=0;

                        for(auto x: ts)
                        {
                            if(used2[x])continue;
                            dfs2(x);
                            if(cmp.size()>1)
                            {
                                kmp++;
                                break;
                            }
                            cmp.clear();
                        }

                        ll nn=ll(kottacmp.size());
                        ans+=nn-(!kmp);

                        for(auto x: kottacmp)
                            g1[x].clear(),g2[x].clear();

                            ts.clear();
                            kottacmp.clear();
                            cmp.clear();
                    }

                    cout<<ans;

                    rt 0;

                    }


                    #include <bits/stdc++.h>

                    typedef long long ll;
                    typedef long double ld;
                    #define rep(i,a,n) for(ll i=(a); i<(n); i++)
                    #define per(i,a,n) for(ll i=(n-1); i>=(a); i--)
                    #define F first
                    #define S second
                    #define maxx(a,b) a=max(a,b)
                    #define minn(a,b) a=min(a,b)
                    #define db(x) cerr<<#x<<" = "<<x<<endl
                    #define N 1111111
                    #define inf 1234567890123456789
                    #define mod 1000000007
                    #define rt return

                    using namespace std;

                    vector<ll> g1[N],g2[N],g[N],ts,cmp,kottacmp;
                    ll n,m,price[N],used1[N],used[N],used2[N];
                    set<int> s;

                    void dfs1(ll v)
                    {
                        used1[v]=1;
                        for(auto x: g1[v])
                            if(!used1[x])dfs1(x);
                        ts.push_back(v);
                    }

                    void dfs2(ll v)
                    {
                        used2[v]=1;
                        cmp.push_back(v);
                        for(auto x: g2[v])
                            if(!used2[x])dfs2(x);
                    }

                    void dfschik(int v)
                    {
                        used[v]=1;
                        kottacmp.push_back(v);
                        for(auto x: g[v])
                            if(!used[x])dfschik(x);
                    }

                    int main()
                    {
                    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

                    cin>>n;
                    cin>>m;

                    rep(i,0,m)
                    {
                        ll j,k; cin>>j>>k;
                        g1[j].push_back(k);
                        g2[k].push_back(j);
                        g[j].push_back(k);
                        g[k].push_back(j);
                    }

                    ll ans=0;

                    rep(q,1,n+1)
                    {
                        if(g[q].empty())continue;
                        if(!used[q])dfschik(q);
                        else continue;

                        for(auto x: kottacmp)
                            s.insert(x);

                        for(auto x: kottacmp)
                        if(!used1[x])dfs1(x);

                        reverse(ts.begin(),ts.end());

                        ll kmp=0;

                        for(auto x: s)
                            g1[x].clear();

                        for(auto x: ts)
                        {
                            if(used2[x])continue;
                            dfs2(x);
                            if(cmp.size()>1)
                            {
                                ans+=ll(cmp.size());
                                for(auto x: cmp)
                                    s.erase(x),g2[x].clear();
                                    kmp++;
                            }
                            cmp.clear();
                        }

                        if(kmp>0)
                            ans+=ll(s.size());
                        else
                            ans+=ll(s.size())-1;

                        for(auto x: s)
                            g1[x].clear(),g2[x].clear();

                            ts.clear();
                            kottacmp.clear();
                            s.clear();
                            cmp.clear();
                    }

                    cout<<ans;

                    rt 0;

                    }

/*
3 6
1 2
1 3
2 1
2 3
3 1
3 2
*/


                    #include <bits/stdc++.h>

                    typedef long long ll;
                    typedef long double ld;
                    #define rep(i,a,n) for(ll i=(a); i<(n); i++)
                    #define per(i,a,n) for(ll i=(n-1); i>=(a); i--)
                    #define F first
                    #define S second
                    #define maxx(a,b) a=max(a,b)
                    #define minn(a,b) a=min(a,b)
                    #define db(x) cerr<<#x<<" = "<<x<<endl
                    #define N 1111111
                    #define inf 1234567890123456789
                    #define mod 1000000007
                    #define rt return

                    using namespace std;

                    vector<ll> g1[N],g2[N],g[N],ts,cmp,kottacmp;
                    ll n,m,price[N],used1[N],used[N],used2[N];
                    set<int> s;

                    void dfs1(ll v)
                    {
                        used1[v]=1;
                        for(auto x: g1[v])
                            if(!used1[x])dfs1(x);
                        ts.push_back(v);
                    }

                    void dfs2(ll v)
                    {
                        used2[v]=1;
                        cmp.push_back(v);
                        for(auto x: g2[v])
                            if(!used2[x])dfs2(x);
                    }

                    void dfschik(int v)
                    {
                        used[v]=1;
                        kottacmp.push_back(v);
                        for(auto x: g[v])
                            if(!used[x])dfschik(x);
                    }

                    int main()
                    {
                    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

                    cin>>n;
                    cin>>m;

                    rep(i,0,m)
                    {
                        ll j,k; cin>>j>>k;
                        g1[j].push_back(k);
                        g2[k].push_back(j);
                        g[j].push_back(k);
                        g[k].push_back(j);
                    }

                    ll ans=0;

                    rep(q,1,n+1)
                    {
                        if(g[q].empty())continue;
                        if(!used[q])dfschik(q);
                        else continue;

                        for(auto x: kottacmp)
                            s.insert(x);

                        for(auto x: kottacmp)
                        if(!used1[x])dfs1(x);

                        reverse(ts.begin(),ts.end());

                        ll kmp=0;

                        for(auto x: s)
                            g1[x].clear();

                        for(auto x: ts)
                        {
                            if(used2[x])continue;
                            dfs2(x);
                            if(cmp.size()>1)
                            {
                                ans+=ll(cmp.size());
                                for(auto x: cmp)
                                    s.erase(x),g2[x].clear();
                                    kmp++;
                            }
                            cmp.clear();
                        }

                        if(kmp>0)
                            ans+=ll(s.size());
                        else
                            ans+=ll(s.size())-1;

                            ts.clear();
                            kottacmp.clear();
                            s.clear();
                            cmp.clear();
                    }

                    cout<<ans;

                    rt 0;

                    }


                    #include <bits/stdc++.h>

                    typedef long long ll;
                    typedef long double ld;
                    #define rep(i,a,n) for(ll i=(a); i<(n); i++)
                    #define per(i,a,n) for(ll i=(n-1); i>=(a); i--)
                    #define F first
                    #define S second
                    #define maxx(a,b) a=max(a,b)
                    #define minn(a,b) a=min(a,b)
                    #define db(x) cerr<<#x<<" = "<<x<<endl
                    #define N 1111111
                    #define inf 1234567890123456789
                    #define mod 1000000007
                    #define rt return

                    using namespace std;

                    vector<ll> g1[N],g2[N],g[N],ts,cmp,kottacmp;
                    ll n,m,price[N],used1[N],used[N],used2[N];
                    set<int> s;

                    void dfs1(ll v)
                    {
                        used1[v]=1;
                        for(auto x: g1[v])
                            if(!used1[x])dfs1(x);
                        ts.push_back(v);
                    }

                    void dfs2(ll v)
                    {
                        used2[v]=1;
                        cmp.push_back(v);
                        for(auto x: g2[v])
                            if(!used2[x])dfs2(x);
                    }

                    void dfschik(int v)
                    {
                        used[v]=1;
                        kottacmp.push_back(v);
                        for(auto x: g[v])
                            if(!used[x])dfschik(x);
                    }

                    int main()
                    {
                    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

                    cin>>n;
                    cin>>m;

                    rep(i,0,m)
                    {
                        ll j,k; cin>>j>>k;
                        g1[j].push_back(k);
                        g2[k].push_back(j);
                        g[j].push_back(k);
                        g[k].push_back(j);
                    }

                    ll ans=0;

                    rep(q,1,n+1)
                    {
                        if(g[q].empty())continue;
                        if(!used[q])dfschik(q);
                        else continue;

                        for(auto x: kottacmp)
                            s.insert(x);

                        for(auto x: kottacmp)
                        if(!used1[x])dfs1(x);

                        reverse(ts.begin(),ts.end());

                        ll kmp=0;

                        for(auto x: s)
                            g1[x].clear();

                        for(auto x: ts)
                        {
                            if(used2[x])continue;
                            dfs2(x);
                            if(cmp.size()>1)
                            {
                                ans+=ll(cmp.size());
                                for(auto x: cmp)
                                    s.erase(x),g2[x].clear();
                                    kmp++;
                            }
                            cmp.clear();
                        }

                        ans+=ll(s.size())-1+kmp;

                        for(auto x: s)
                            g1[x].clear(),g2[x].clear();

                            ts.clear();
                            kottacmp.clear();
                            s.clear();
                            cmp.clear();
                    }

                    cout<<ans;

                    rt 0;

                    }

/*
3 6
1 2
1 3
2 1
2 3
3 1
3 2
*/


//In the name of GOD
//SMani24
#include<bits/stdc++.h>
#define debug(X) cerr<<#X<<"="<<(X)<<endl
#define endl "\n"
using namespace std;
typedef long long int ll;
const int mn=1e5+100;
const int inf=1e9;
const int mod=1e9+7;
int n,m,g[mn],f=0,t[mn],cnt=1,ans=0,vor[mn][2];
bool ch[mn];
vector<int>yal[mn][2],topol;
//vector<int>ybm[mn];
void dfs(int v,bool w){
    ch[v]=1;
    for(int u:yal[v][w]){
        if(ch[u]){
            continue;
        }
        dfs(u,w);
    }
    if(!w){
        //ans++;
        topol.push_back(v);
    }
    else{
        g[v]=cnt;
        t[cnt]++;
    }
    return ;
}
void dfs2(int v){
    ch[v]=1;
    if(t[g[v]]>1){
        f=1;
    }
    //debug(v);
    for(int u:yal[v][0]){
        if(ch[u]){
            continue;
        }
        //debug(u);
        ans++;
        dfs2(u);
    }
    return ;
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cout<<setprecision(30);
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>vor[i][0]>>vor[i][1];
        vor[i][0]--,vor[i][1]--;
        yal[vor[i][0]][0].push_back(vor[i][1]);
        yal[vor[i][1]][1].push_back(vor[i][0]);
    }
    for(int i=0;i<n;i++){
        if(ch[i]){
            continue;
        }
        dfs(i,0);
    }
    memset(ch,0,sizeof ch);
    reverse(topol.begin(),topol.end());
    for(int i:topol){
        if(ch[i]){
            continue;
        }
        dfs(i,1);
        cnt++;
    }
    memset(ch,0,sizeof ch);
    ans=0;
    for(int i=0;i<n;i++){
        if(ch[i]){
            continue;
        }
        dfs2(i);
        ans+=f;
        f=0;
    }
    cout<<ans<<endl;
    return 0;
}


//In the name of GOD
//SMani24
#include<bits/stdc++.h>
#define debug(X) cerr<<#X<<"="<<(X)<<endl
#define endl "\n"
using namespace std;
typedef long long int ll;
const int mn=1e5+100;
const int inf=1e9;
const int mod=1e9+7;
int n,m,g[mn],t[mn],cnt=1,ans=0,vor[mn][2];
bool ch[mn];
vector<int>yal[mn][2],topol;
vector<int>ybm[mn];
void dfs(int v,bool w){
    ch[v]=1;
    for(int u:yal[v][w]){
        if(ch[u]){
            continue;
        }
        dfs(u,w);
    }
    if(!w){
        //ans++;
        topol.push_back(v);
    }
    else{
        g[v]=cnt;
        t[cnt]++;
    }
    return ;
}
void dfs2(int v){
    ch[v]=1;
    //debug(v);
    for(int u:ybm[v]){
        if(ch[u]){
            continue;
        }
        //debug(u);
        ans++;
        dfs2(u);
    }
    return ;
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cout<<setprecision(30);
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>vor[i][0]>>vor[i][1];
        vor[i][0]--,vor[i][1]--;
        yal[vor[i][0]][0].push_back(vor[i][1]);
        yal[vor[i][1]][1].push_back(vor[i][0]);
    }
    for(int i=0;i<n;i++){
        if(ch[i]){
            continue;
        }
        dfs(i,0);
    }
    memset(ch,0,sizeof ch);
    reverse(topol.begin(),topol.end());
    for(int i:topol){
        if(ch[i]){
            continue;
        }
        dfs(i,1);
        cnt++;
    }
    for(auto i:vor){
        if(g[i[0]]==g[i[1]]){
            continue;
        }
        //debug(i[0]);
        //debug(i[1]);
        ybm[g[i[0]]].push_back(g[i[1]]);
    }
    memset(ch,0,sizeof ch);
    ans=0;
    for(int i=1;i<cnt;i++){
        dfs2(i);
        if(t[i]!=1){
            ans+=t[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}


//In the name of GOD
//SMani24
#include<bits/stdc++.h>
#define debug(X) cerr<<#X<<"="<<(X)<<endl
#define endl "\n"
using namespace std;
typedef long long int ll;
const int mn=1e5+100;
const int inf=1e9;
const int mod=1e9+7;
int n,m,g[mn],f=0,t[mn],cnt=1,ans=0,vor[mn][2];
bool ch[mn];
vector<int>yal[mn][2],yala[mn],topol;
//vector<int>ybm[mn];
void dfs(int v,bool w){
    ch[v]=1;
    for(int u:yal[v][w]){
        if(ch[u]){
            continue;
        }
        dfs(u,w);
    }
    if(!w){
        //ans++;
        topol.push_back(v);
    }
    else{
        g[v]=cnt;
        t[cnt]++;
    }
    return ;
}
void dfs2(int v){
    ch[v]=1;
    if(t[g[v]]>1){
        f=1;
    }
    //debug(v);
    for(int u:yala[v]){
        if(ch[u]){
            continue;
        }
        //debug(u);
        ans++;
        dfs2(u);
    }

    return ;
}
int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cout<<setprecision(30);
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>vor[i][0]>>vor[i][1];
        vor[i][0]--,vor[i][1]--;
        yala[vor[i][0]].push_back(vor[i][1]);
        yala[vor[i][1]].push_back(vor[i][0]);
        yal[vor[i][0]][0].push_back(vor[i][1]);
        yal[vor[i][1]][1].push_back(vor[i][0]);
    }
    for(int i=0;i<n;i++){
        if(ch[i]){
            continue;
        }
        dfs(i,0);
    }
    memset(ch,0,sizeof ch);
    reverse(topol.begin(),topol.end());
    for(int i:topol){
        if(ch[i]){
            continue;
        }
        dfs(i,1);
        cnt++;
    }
    memset(ch,0,sizeof ch);
    ans=0;
    for(int i=0;i<n;i++){
        if(ch[i]){
            continue;
        }
        dfs2(i);
        ans+=f;
        f=0;
    }
    cout<<ans<<endl;
    return 0;
}


//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define ll long long int
#define ld long double
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define all(x) x.begin(),x.end()
#define F first
#define S second
#define fo(i,n) for(int i=0;i<(n);i++)
#define inp(a) int a;cin>>a;
#define inpa(a,n)vector<int> a(n);fo(i,n)cin>>a[i];
#define printclock cerr<<"Time : "<<1000*(ld)clock()/(ld)CLOCKS_PER_SEC<<"ms\n";
using namespace std;
#define int ll
// #define MAX 20
#define INF (int)1e18

template<class T> ostream& operator<<(ostream& cout,vector<T> V)
{cout<<"[ ";for(auto v:V)cout<<v<<' ';return cout<<']';}
template<class L,class R> ostream& operator<<(ostream& cout,pair<L, R> P)
{return cout<<'('<<P.F<<','<< P.S<<')';}

vector<set<int>> a,b;
bool loop;
int ct;

vector<int> done;
void dfs(int node)
{
	ct++;
	done[node]=1;
	for(int i:a[node])
	{
		if(done[i]==1)
		{
			loop=1;
			continue;
		}
		if(done[i]==2)
		{
			continue;
		}
		dfs(i);
	}
	done[node]=2;
}

int chk(int n,int m,auto a,auto b)
{
	vector<int> pre;
	fo(i,n)
		if(!b[i].size())
			pre.pb(i);
	done.resize(n);
	int ans=-(int)pre.size();
	for(int i:pre)
	{
		ct=0;
		loop=0;
		dfs(i);
		ans+=ct+loop;
		// cerr<<i<<" : "<<ct<<'+'<<loop<<endl;
	}
	// cerr<<ans<<'\n';
	fo(i,n)
	{
		if(done[i]==0 && b[i].size())
			ans++;
	}
	return ans;
}

signed main()
{
	fio
	inp(n) inp(m)
	a.resize(n);
	b.resize(n);
	fo(i,m)
	{
		inp(x) inp(y)
		x--,y--;
		a[x].insert(y);
		b[y].insert(x);
	}
	int pre=0;
	fo(i,n)
	{
		if(b[i].size()==0 && a[i].size()==0)
			pre++;
	}
	cout<<chk(n,m,a,b)<<'\n';
	printclock;
}


//#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define ll long long int
#define ld long double
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define all(x) x.begin(),x.end()
#define F first
#define S second
#define fo(i,n) for(int i=0;i<(n);i++)
#define inp(a) int a;cin>>a;
#define inpa(a,n)vector<int> a(n);fo(i,n)cin>>a[i];
#define printclock cerr<<"Time : "<<1000*(ld)clock()/(ld)CLOCKS_PER_SEC<<"ms\n";
using namespace std;
#define int ll
// #define MAX 20
#define INF (int)1e18

template<class T> ostream& operator<<(ostream& cout,vector<T> V)
{cout<<"[ ";for(auto v:V)cout<<v<<' ';return cout<<']';}
template<class L,class R> ostream& operator<<(ostream& cout,pair<L, R> P)
{return cout<<'('<<P.F<<','<< P.S<<')';}

int chk(int n,int m,auto a,auto b)
{
	queue<int> done;
	fo(i,n)
	{
		if(!b[i].size())
		{
			done.push(i);
		}
	}
	int ans=-1*(int)done.size();
	int left=n-done.size();
	while(left || done.size())
	{
		if(!done.size())
		{
			return ans+left;
		}

		int curr=done.front();
		done.pop();
		ans++;
		for(int i:a[curr])
		{
			b[i].erase(curr);
			if(!b[i].size())
			{
				left--;
				done.push(i);
			}
		}
	}
	return ans;
}

signed main()
{
	fio
	inp(n) inp(m)
	vector<set<int>> a(n),b(n);
	fo(i,m)
	{
		inp(x) inp(y)
		x--,y--;
		a[x].insert(y);
		b[y].insert(x);
	}
	int pre=0;
	fo(i,n)
	{
		if(b[i].size()==0 && a[i].size()==0)
			pre++;
	}
	if(chk(n,m,a,b)!=-1)
		cout<<chk(n,m,a,b)<<'\n';
	else
		cout<<n-pre<<'\n';
	printclock;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define v d[t].to
const int N = 1e5 + 10;
using namespace std;
struct ll{int to,last;}d[N<<1];
struct node{
 int n,k,dis;
 inline bool operator < (const node & b)const{return dis > b.dis;}
};
int n,m,num,K,lim,head[N],dis[N][101],D[N];
priority_queue<node>qe;
inline int read(){
 int k=0,f=0;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;
 for(;c<='9'&&c>='0';c=getchar())k=(k<<1)+(k<<3)+c-'0';return f?-k:k;
}
void spfa(){
 memset(dis,-1,sizeof(dis));
 for(int i = 1;i <= n;i ++)
 dis[i][D[i]] = 0,qe.push((node){i,D[i],0});
 while(!qe.empty()){
  node u = qe.top(); qe.pop();
  if(dis[u.n][u.k] < u.dis)continue;
  for(int t = head[u.n]; t;t = d[t].last)
  if(dis[v][u.k] == -1){
   dis[v][u.k] = dis[u.n][u.k] + 1;
   qe.push((node){v,u.k,dis[v][u.k]});
  }
 }
}
void add(int a,int b){d[++num]=(ll){b,head[a]};head[a]=num;}
int main(){
 n = read(); m = read(); K = read(); lim = read();
 for(int i = 1;i <= n;i ++)D[i] = read();
 while(m --){
  int a = read(),b = read();
  add(a, b); add(b, a);
 } spfa();
 for(int ans = 0,i = 1;i <= n;i ++){
  sort(dis[i] + 1,dis[i] + K + 1);
  for(int j = 1;j <= lim;j ++)ans += dis[i][j];
  printf("%d ",ans); ans = 0;
 }
 return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define l(s) int(s.size())
#define pb push_back
int main()
{
	int n,m,k,s;
	cin>>n>>m>>k>>s;
	vector<int> a(n);
	for(int i=0;i<n;i++)
		cin>>a[i],a[i]--;
	vector<vector<int> > g(n);
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		g[x].pb(y);
		g[y].pb(x);
	}
	vector<vector<int> > dist(k,vector<int>(n,-1));
	for(int type=0;type<k;type++)
	{
		vector<int> que;
		for(int i=0;i<n;i++)
		{
			if(a[i]==type)
			{
				dist[type][i]=0;
				que.pb(i);
			}
		}
		for(int b=0;b<l(que);b++)
		{
			for(int i=0;i<l(g[que[b]]);i++)
			{
				int u=g[que[b]][i];
				if(dist[type][u]==-1)
				{
					dist[type][u]=dist[type][que[b]]+1;
					que.pb(u);
				}
			}
		}
	}
	vector<int> d(k);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<k;j++)
			d[j]=dist[j][i];
		sort(d.begin(),d.end());
		long long sum=0;
		for(int j=0;j<s;j++)
			sum+=d[j];
		if(i>0)
			cout<<' ';
		cout<<sum;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>v[1000005],g[1000005];
int ans[1000005][105],a[1000005];
int sol=0;
queue<int>q;
int main()
{
    int n,m,k,s;
    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);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    memset(ans,-1,sizeof(ans));
    for(int c=1;c<=k;c++)
	{
        for(int i=0;i<v[c].size();i++)
		{
            q.push(v[c][i]);
            ans[v[c][i]][c]=0;
        }
        while(!q.empty())
		{
            int x=q.front();
            q.pop();
            for(int i=0;i<g[x].size();i++)
			{
                if(ans[g[x][i]][c]==-1)
				{
                    ans[g[x][i]][c]=ans[x][c]+1;
                    q.push(g[x][i]);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
	{
        sol=0;
        sort(ans[i]+1,ans[i]+1+k);
        for (int j=1;j<=s;j++)
            sol+=ans[i][j];
        printf("%d ",sol);
    }
}


#include<bits/stdc++.h>
using namespace std;
vector<int> v[10005],g[10005];
int dp[10005][110],a[10005];
queue<int> q;
int main()
{
    int n,m,k,s;
    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);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    memset(dp,-1,sizeof(dp));
    for (int c=1;c<=k;c++)
	{
        for(vector<int>::iterator it=v[c].begin();it!=v[c].end();it++)
		{
            q.push(*it);
            dp[*it][c]=0;
        }
        while(!q.empty())
		{
            int x=q.front();
            q.pop();
            for(vector<int>::iterator it=g[x].begin();it!=g[x].end();it++)
			{
                if(dp[*it][c]==-1)
				{
                    dp[*it][c]=dp[x][c]+1;
                    q.push(*it);
                }
            }
        }
    }
    int ans=0;
    for (int i=1;i<=n;i++)
	{
        ans=0;
        sort(dp[i]+1,dp[i]+1+k);
        for (int j=1;j<=s;j++)
            ans+=dp[i][j];
        printf("%d ",ans);
    }
}


#include<bits/stdc++.h>
using namespace std;
#define l(s) int(s.size())
#define pb push_back
#define ppb pop_back
#define pf push_front
#define ppf pop_front
#define pu push
#define pp pop
#define f front
#define b back
int main()
{
	int n,m,k,s;
	cin>>n>>m>>k>>s;
	vector<int> a(n);
	for(int i=0;i<n;i++)
		cin>>a[i],a[i]--;
	vector<vector<int> > g(n);
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--;
		y--;
		g[x].pb(y);
		g[y].pb(x);
	}
	vector<vector<int> >dist(k,vector<int>(n,-1));
	for(int type=0;type<k;type++)
	{
		vector<int> que;
		for(int i=0;i<n;i++)
		{
			if(a[i]==type)
			{
				dist[type][i]=0;
				que.pb(i);
			}
		}
		for(int b=0;b<l(que);b++)
		{
			for(int i=0;i<l(g[que[b]]);i++)
			{
				int u=g[que[b]][i];
				if(dist[type][u]==-1)
				{
					dist[type][u]=dist[type][que[b]]+1;
					que.pb(u);
				}
			}
		}
	}
	vector<int> d(k);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<k;j++)
			d[j]=dist[j][i];
		sort(d.begin(),d.end());
		long long sum=0;
		for(int j=0;j<s;j++)
			sum+=d[j];
		if(i>0)
			cout<<' ';
		cout<<sum;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
vector<int>v[1000005],g[1000005];
int ans[1000005][105],a[1000005];
int sol=0;
queue<int>q;
int main()
{
    int n,m,k,s;
    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);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    memset(ans,-1,sizeof(ans));
    for(int c=1;c<=k;c++)
	{
        for(int i=0;i<v[c].size();i++)
		{
            q.push(v[c][i]);
            ans[v[c][i]][c]=0;
        }
        while(!q.empty())
		{
            int x=q.front();
            q.pop();
            for(int i=0;i<g[x].size();i++)
			{
                if(ans[g[x][i]][c]==-1)
				{
                    ans[g[x][i]][c]=ans[x][c]+1;
                    q.push(g[x][i]);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
	{
        sol=0;
        sort(ans[i]+1,ans[i]+1+k);
        for (int j=1;j<=s;j++)
            sol+=ans[i][j];
        printf("%d ",sol);
    }
    exit(0);
}


#include<bits/stdc++.h>
using namespace std;
vector<int>v[1000005],g[1000005];
int ans[1000005][105],a[1000005];
int sol=0;
queue<int>q;
int main()
{
    int n,m,k,s;
    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);
        g[x].push_back(y);
        g[y].push_back(x);
    }
    memset(ans,-1,sizeof(ans));
    for(int c=1;c<=k;c++)
	{
        for(int i=0;i<v[c].size();i++)
		{
            q.push(v[c][i]);
            ans[v[c][i]][c]=0;
        }
        while(!q.empty())
		{
            int x=q.front();
            q.pop();
            for(int i=0;i<g[x].size();i++)
			{
                if(ans[g[x][i]][c]==-1)
				{
                    ans[g[x][i]][c]=ans[x][c]+1;
                    q.push(g[x][i]);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
	{
        sol=0;
        sort(ans[i]+1,ans[i]+1+k);
        for (int j=1;j<=s;j++)
            sol+=ans[i][j];
        printf("%d ",sol);
    }
    return 0;
}


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

using namespace std;
const int N=1e5+5;
int n,s,k,m;

vector<int> V[N],upd[N];
bool notV[N];
int d[N][110];
int id[N],q[N],top;

int main()
{
    //freopen("i","r",stdin);
    //freopen("o","w",stdout);

    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",id+i);
        q[++top]=i;
        d[i][id[i]]=1;
        upd[i].push_back(id[i]);
    }

    for(int u,v,i=0;i<m;i++){
        scanf("%d%d",&u,&v),
        V[u].push_back(v),
        V[v].push_back(u);
    }

    memset(notV,1,sizeof(notV));

    int u,v,l,up;
    while(top){
        u=q[top--];
        notV[u]=true;
        l=V[u].size();
        while(!upd[u].empty()){
            up=upd[u].back();upd[u].pop_back();
            for(int i=0;i<l;i++){
                v=V[u][i];
                if(!d[v][up]||d[v][up]>d[u][up]+1){
                    d[v][up]=d[u][up]+1;
                    upd[v].push_back(up);
                    if(notV[v]){
                        notV[v]=false;
                        q[++top]=v;
                    }
                }
            }
        }
    }

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


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

using namespace std;
const int N=1e5+5;
int n,s,k,m;

vector<int> V[N],upd[N];
bool notV[N];
int d[N][110];
int id[N],q[N],top;

int main()
{
    //freopen("i","r",stdin);
    //freopen("o","w",stdout);

    memset(d,-1,sizeof d);

    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",id+i);
        q[++top]=i;
        d[i][id[i]]=0;
        upd[i].push_back(id[i]);
    }

    for(int u,v,i=0;i<m;i++){
        scanf("%d%d",&u,&v),
        V[u].push_back(v),
        V[v].push_back(u);
    }

    memset(notV,1,sizeof(notV));

    int u,v,l,up;
    while(top){
        u=q[top--];
        notV[u]=true;
        l=V[u].size();
        while(!upd[u].empty()){
            up=upd[u].back();upd[u].pop_back();
            for(int i=0;i<l;i++){
                v=V[u][i];
                if(!~d[v][up]||d[v][up]>d[u][up]+1){
                    d[v][up]=d[u][up]+1;
                    upd[v].push_back(up);
                    if(notV[v]){
                        notV[v]=false;
                        q[++top]=v;
                    }
                }
            }
        }
    }

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


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

using namespace std;
const int N=1e5+5;
int n,s,k,m;

vector<int> V[N],upd[N];
bool notV[N];
int d[N][110];
int id[N],q[N],top;

int main()
{
    //freopen("i","r",stdin);
    //freopen("o","w",stdout);

    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",id+i);
        q[++top]=i;
        d[i][id[i]]=1;
        upd[i].push_back(id[i]);
    }

    for(int u,v,i=0;i<m;i++){
        scanf("%d%d",&u,&v),
        V[u].push_back(v),
        V[v].push_back(u);
    }

    memset(notV,1,sizeof(notV));

    int u,v,l,up;
    while(top){
        u=q[top--];
        notV[u]=true;
        l=V[u].size();
        while(!upd[u].empty()){
            up=upd[u].back();upd[u].pop_back();
            for(int i=0;i<l;i++){
                v=V[u][i];
                if(!d[v][up]||d[v][up]>d[u][up]+1){
                    d[v][up]=d[u][up]+1;
                    upd[v].push_back(up);
                    if(notV[v]){
                        notV[v]=false;
                        q[++top]=v;
                    }
                }
            }
        }
    }

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


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

using namespace std;
const int N=1e5+5;
int n,s,k,m;

vector<int> V[N],upd[N];
bool notV[N];
int d[N][110];
int id[N],q[N],top;

int main()
{
    //freopen("i","r",stdin);
    //freopen("o","w",stdout);

    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",id+i);
        q[++top]=i;
        d[i][id[i]]=1;
        upd[i].push_back(id[i]);
    }

    for(int u,v,i=0;i<m;i++){
        scanf("%d%d",&u,&v),
        V[u].push_back(v),
        V[v].push_back(u);
    }

    memset(notV,1,sizeof(notV));

    int u,v,l,up;
    while(top){
        u=q[top--];
        notV[u]=true;
        l=V[u].size();
        while(!upd[u].empty()){
            up=upd[u].back();upd[u].pop_back();
            for(int i=0;i<l;i++){
                v=V[u][i];
                if(!d[v][up]||d[v][up]>d[u][up]+1){
                    d[v][up]=d[u][up]+1;
                    upd[v].push_back(up);
                    if(notV[v]){
                        notV[v]=false;
                        q[++top]=v;
                    }
                }
            }
        }
    }

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


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

using namespace std;
const int N=1e5+5;
int n,s,k,m;

vector<int> V[N],upd[N];
bool notV[N];
int d[N][110];
int id[N],q[N],top;

int main()
{
    //freopen("i","r",stdin);
    //freopen("o","w",stdout);

    memset(d,-1,sizeof d);

    scanf("%d%d%d%d",&n,&m,&k,&s);
    for(int i=1;i<=n;i++){
        scanf("%d",id+i);
        d[i][id[i]]=0;
        upd[i].push_back(id[i]);
    }

    for(int u,v,i=0;i<m;i++){
        scanf("%d%d",&u,&v),
        V[u].push_back(v),
        V[v].push_back(u);
    }

    memset(notV,1,sizeof(notV));

    top=1;
    q[1]=1;

    int u,v,l,up;
    while(top){
        u=q[top--];
        notV[u]=true;
        l=V[u].size();
        while(!upd[u].empty()){
            up=upd[u].back();upd[u].pop_back();
            for(int i=0;i<l;i++){
                v=V[u][i];
                if(!~d[v][up]||d[v][up]>d[u][up]+1){
                    d[v][up]=d[u][up]+1;
                    upd[v].push_back(up);
                    if(notV[v]){
                        notV[v]=false;
                        q[++top]=v;
                    }
                }
            }
        }
    }

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


#include <iostream>
#include <set>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;

struct graph
{
    list <int> adj;
    set<int> acq;
};

int main ()
{
    ios_base::sync_with_stdio(false);
    int v,e,u,w,k,s;
    cin >> v >> e >> k >> s;
    graph G[v+1];

    stack <pair <int,int>> * g1=new stack <pair <int,int>>, *g2=new stack <pair <int,int>>;
    int left=v, order=1, town, good;
    int result[v+1]={};

    for (int i=1;i<=v;i++)
    {
        cin >> u;
        G[i].acq.insert(u);
        g1->push({i,u});
    }

    for (int i=0;i<e;i++)
    {
        cin >> u >> w;
        G[u].adj.push_back(w);
        G[w].adj.push_back(u);
    }

    while(left)
    {
        while(!g1->empty())
        {
            town=g1->top().first;
            good=g1->top().second;
            g1->pop();

            for (int x: G[town].adj)
                if (G[x].acq.size() < s && G[x].acq.find(good)==G[x].acq.end())
                {
                    result[x]+=order;
                    G[x].acq.insert(good);
                    g2->push({x,good});
                    if (G[x].acq.size()==s)
                        left--;
                }
        }
        swap(g1,g2);
        order++;
    }

    for (int i=1;i<=v;i++)
        cout << result[i] << " ";

}


#include <iostream>
#include <set>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;

struct graph
{
    list <int> adj;
    bool * acq;
    int acq_size=1;
};

int main ()
{
    ios_base::sync_with_stdio(false);
    int v,e,u,w,k,s;
    cin >> v >> e >> k >> s;
    graph G[v+1];
    for (int i=1;i<=v;i++)
    {
        G[i].acq=new bool [k+1];
        for (int j=1;j<=k;j++)
            G[i].acq[j]=false;
    }

    stack <pair <int,int>> * g1=new stack <pair <int,int>>, *g2=new stack <pair <int,int>>;
    int left=v, order=1, town, good;
    int result[v+1]={};

    for (int i=1;i<=v;i++)
    {
        cin >> u;
        G[i].acq[u]=true;
        g1->push({i,u});
    }

    for (int i=0;i<e;i++)
    {
        cin >> u >> w;
        G[u].adj.push_back(w);
        G[w].adj.push_back(u);
    }

    while(left)
    {
        while(!g1->empty())
        {
            town=g1->top().first;
            good=g1->top().second;
            g1->pop();

            for (int x: G[town].adj)
                if (G[x].acq_size < s && !G[x].acq[good])
                {
                    result[x]+=order;
                    G[x].acq[good]=true;
                    G[x].acq_size++;
                    g2->push({x,good});
                    if (G[x].acq_size==s)
                        left--;
                }
        }
        swap(g1,g2);
        order++;
    }

    for (int i=1;i<=v;i++)
        cout << result[i] << " ";

}


#include <iostream>
#include <set>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;

struct graph
{
    list <int> adj;
    //set<int> acq;
    bool * acq;
    int acq_size=1;
};

int main ()
{
    ios_base::sync_with_stdio(false);
    int v,e,u,w,k,s;
    cin >> v >> e >> k >> s;
    graph G[v+1];
    for (int i=1;i<=v;i++)
    {
        G[i].acq=new bool [k];
        for (int j=0;j<k;j++)
            G[i].acq[j]=false;
    }

    stack <pair <int,int>> * g1=new stack <pair <int,int>>, *g2=new stack <pair <int,int>>;
    int left=v, order=1, town, good;
    int result[v+1]={};

    for (int i=1;i<=v;i++)
    {
        cin >> u;
        G[i].acq[u]=true;
        //G[i].acq.insert(u);
        g1->push({i,u});
    }

    for (int i=0;i<e;i++)
    {
        cin >> u >> w;
        G[u].adj.push_back(w);
        G[w].adj.push_back(u);
    }

    while(left)
    {
        while(!g1->empty())
        {
            town=g1->top().first;
            good=g1->top().second;
            g1->pop();

            for (int x: G[town].adj)
                if (G[x].acq_size < s && !G[x].acq[good])
                {
                    result[x]+=order;
                    G[x].acq[good]=true;
                    G[x].acq_size++;
                    g2->push({x,good});
                    if (G[x].acq_size==s)
                        left--;
                }
        }
        swap(g1,g2);
        order++;
    }

    for (int i=1;i<=v;i++)
        cout << result[i] << " ";

}


#include <iostream>
#include <set>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;

struct graph
{
    list <int> adj;
    set<int> acq;
};

int main ()
{
    ios_base::sync_with_stdio(false);
    int v,e,u,w,k,s;
    cin >> v >> e >> k >> s;
    graph G[v+1];

    stack <pair <int,int>> * g1=new stack <pair <int,int>>, *g2=new stack <pair <int,int>>;
    int left=v, order=1, town, good;
    int result[v+1]={};

    for (int i=1;i<=v;i++)
    {
        cin >> u;
        G[i].acq.insert(u);
        g1->push({i,u});
    }

    for (int i=0;i<e;i++)
    {
        cin >> u >> w;
        G[u].adj.push_back(w);
        G[w].adj.push_back(u);
    }

    //stos -  miasto, towar
    while(left)
    {
        while(!g1->empty())
        {
            town=g1->top().first;
            good=g1->top().second;
            g1->pop();

            for (int x: G[town].adj)
                if (G[x].acq.size() <= s && G[x].acq.find(good)==G[x].acq.end())
                {
                    if (G[x].acq.size()<s)
                        result[x]+=order;
                    G[x].acq.insert(good);
                    g2->push({x,good});
                    if (G[x].acq.size()==s)
                        left--;
                }
        }
        swap(g1,g2);
        order++;
    }

    for (int i=1;i<=v;i++)
        cout << result[i] << " ";

}


#include <iostream>
#include <set>
#include <stack>
#include <algorithm>
#include <list>
using namespace std;

struct graph
{
    int result=0;
    list <int> adj;
    bool * acq;
    int acq_size=1;
};

int main ()
{
    ios_base::sync_with_stdio(false);
    int v,e,u,w,k,s;
    cin >> v >> e >> k >> s;
    graph G[v+1];
    for (int i=1;i<=v;i++)
    {
        G[i].acq=new bool [k+1];
        for (int j=1;j<=k;j++)
            G[i].acq[j]=false;
    }

    stack <pair <int,int>> * g1=new stack <pair <int,int>>, *g2=new stack <pair <int,int>>;
    int left=v, order=1, town, good;

    for (int i=1;i<=v;i++)
    {
        cin >> u;
        G[i].acq[u]=true;
        g1->push({i,u});
    }

    for (int i=0;i<e;i++)
    {
        cin >> u >> w;
        G[u].adj.push_back(w);
        G[w].adj.push_back(u);
    }

    if (s!=1)
    while(left)
    {
        while(!g1->empty())
        {
            town=g1->top().first;
            good=g1->top().second;
            g1->pop();

            for (int x: G[town].adj)
                if (G[x].acq_size < s && !G[x].acq[good])
                {
                    G[x].result+=order;
                    G[x].acq[good]=true;
                    G[x].acq_size++;
                    g2->push({x,good});
                    if (G[x].acq_size==s)
                        left--;
                }
        }
        swap(g1,g2);
        order++;
    }

    for (int i=1;i<=v;i++)
        cout << G[i].result << " ";

}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define N 101000
#define ls (now<<1)
#define rs ((now<<1)|1)
#define RG register
using namespace std;

inline int read(){
    RG int x=0,o=1; RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=((x<<3)+(x<<1))+ch-'0',ch=getchar();
    return x*o;
}

int n,m,K,S,top,first[N],vis[N],dis[N][110],col[N];
struct mona { int nxt,en; } s[N<<1];
inline void Insert(int x,int y) { s[++top]=(mona) { first[x],y },first[x]=top; }
inline void Bfs(int Col){
	queue<int> Q;
	for(RG int i=1;i<=n;++i)
		if(col[i]==Col) dis[i][Col]=0,Q.push(i),vis[i]=1;
		else vis[i]=0;
	while(!Q.empty()){
		int now=Q.front(); Q.pop();
		for(RG int i=first[now];i;i=s[i].nxt){
			int en=s[i].en; if(vis[en]) continue ;
			vis[en]=1,dis[en][Col]=dis[now][Col]+1,Q.push(en);
		}
	}   return ;
}

int main(){
	n=read(),m=read(),K=read(),S=read();
	for(RG int i=1;i<=n;++i) col[i]=read();
	for(RG int i=1;i<=m;++i){
		int x=read(),y=read();
		Insert(x,y),Insert(y,x);
	}   for(RG int i=1;i<=K;++i) Bfs(i);
	for(RG int i=1;i<=n;++i){ int ans=0;
		sort(dis[i]+1,dis[i]+1+K);
		for(RG int j=1;j<=S;++j) ans+=dis[i][j];
		printf("%d ",ans);
	}
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define N 101000
#define ls (now<<1)
#define rs ((now<<1)|1)
#define RG register
using namespace std;

inline int read(){
    RG int x=0,o=1; RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=((x<<3)+(x<<1))+ch-'0',ch=getchar();
    return x*o;
}

int n,m,K,S,top,first[N],vis[N],dis[N][110],col[N];
struct mona { int nxt,en; } s[N];
inline void Insert(int x,int y) { s[++top]=(mona) { first[x],y },first[x]=top; }
inline void Bfs(int Col){
	queue<int> Q;
	for(RG int i=1;i<=n;++i)
		if(col[i]==Col) dis[i][Col]=0,Q.push(i),vis[i]=1;
		else vis[i]=0;
	while(!Q.empty()){
		int now=Q.front(); Q.pop();
		for(RG int i=first[now];i;i=s[i].nxt){
			int en=s[i].en; if(vis[en]) continue ;
			vis[en]=1,dis[en][Col]=dis[now][Col]+1,Q.push(en);
		}
	}   return ;
}

int main(){
	n=read(),m=read(),K=read(),S=read();
	for(RG int i=1;i<=n;++i) col[i]=read();
	for(RG int i=1;i<=m;++i){
		int x=read(),y=read();
		Insert(x,y),Insert(y,x);
	}   for(RG int i=1;i<=K;++i) Bfs(i);
	for(RG int i=1;i<=n;++i){ int ans=0;
		sort(dis[i]+1,dis[i]+1+K);
		for(RG int j=1;j<=S;++j) ans+=dis[i][j];
		printf("%d ",ans);
	}
}


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define N 101000
#define ls (now<<1)
#define rs ((now<<1)|1)
#define RG register
using namespace std;

inline int read(){
    RG int x=0,o=1; RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=((x<<3)+(x<<1))+ch-'0',ch=getchar();
    return x*o;
}

int n,m,K,S,top,first[N],vis[N],dis[N][110],col[N];
struct mona { int nxt,en; } s[N];
inline void Insert(int x,int y) { s[++top]=(mona) { first[x],y },first[x]=top; }
inline void Bfs(int Col){
	queue<int> Q;
	for(RG int i=1;i<=n;++i)
		if(col[i]==Col) dis[i][Col]=0,Q.push(i),vis[i]=1;
		else vis[i]=0;
	while(!Q.empty()){
		int now=Q.front(); Q.pop();
		for(RG int i=first[now];i;i=s[i].nxt){
			int en=s[i].en; if(vis[en]) continue ;
			vis[en]=1,dis[en][Col]=dis[now][Col]+1,Q.push(en);
		}
	}   return ;
}

int main(){
	n=read(),m=read(),K=read(),S=read();
	for(RG int i=1;i<=n;++i) col[i]=read();
	for(RG int i=1;i<=m;++i){
		int x=read(),y=read();
		Insert(x,y),Insert(y,x);
	}   for(RG int i=1;i<=K;++i) Bfs(i);
	for(RG int i=1;i<=n;++i){ ll ans=0;
		sort(dis[i]+1,dis[i]+1+K);
		for(RG int j=1;j<=S;++j) ans+=dis[i][j];
		printf("%d ",ans);
	}
}


#include <vector>
#include <iostream>
using namespace std;
vector <int> edge[300000] , got[3000] , res[300000] , ruler;
int a[300000] , n , m , k , s , ok[300000] , pre = 0;
void bfs(int type , int cost)
{
	int cur = ruler.size();
	for (int i = pre ; i < cur ; i++)
	{
	//	cout <<"type : "<<type<<" cost : "<<cost<<" " <<ruler[i]<<'\n';
		res[ruler[i]].push_back(cost);
		for (int e = 0 ; e < edge[ruler[i]].size() ; e++)
		{
			if (ok[edge[ruler[i]][e]] != type)
			{
				ok[edge[ruler[i]][e]] = type;
				ruler.push_back(edge[ruler[i]][e]);
			}
		}
	}
	if (cur != ruler.size())
	{
		pre = cur;
		bfs(type , cost + 1);
	}
}
int main()
{
	cin >> n >> m >> k >> s;
	for (int i = 1 ; i <= n ; i++)
	{
		cin >> a[i];
		got[a[i]].push_back(i);
	}
	for (int i = 1 ; i <= m ; i++)
	{
		int u , v;
		cin >> u >> v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	for (int i = 1 ; i <= k ; i++)
	{
		ruler.clear();
		pre = 0;
		for (int e = 0 ; e < got[i].size() ; e++)
		{
			ruler.push_back(got[i][e]);
			ok[got[i][e]] = i;
		}
		bfs(i , 0);
	}
	for (int i = 1 ; i <= n ; i++)
	{
		sort(res[i].begin() , res[i].end());
		long long kq = 0;
		for (int e = 0 ; e < s ; e++)
		{
			kq += res[i][e];
		}
		cout <<kq<<" ";
	}
}


#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
vector <int> edge[300000] , got[3000] , res[300000] , ruler;
int a[300000] , n , m , k , s , ok[300000] , pre = 0;
void bfs(int type , int cost)
{
	int cur = ruler.size();
	for (int i = pre ; i < cur ; i++)
	{
	//	cout <<"type : "<<type<<" cost : "<<cost<<" " <<ruler[i]<<'\n';
		res[ruler[i]].push_back(cost);
		for (int e = 0 ; e < edge[ruler[i]].size() ; e++)
		{
			if (ok[edge[ruler[i]][e]] != type)
			{
				ok[edge[ruler[i]][e]] = type;
				ruler.push_back(edge[ruler[i]][e]);
			}
		}
	}
	if (cur != ruler.size())
	{
		pre = cur;
		bfs(type , cost + 1);
	}
}
int main()
{
	cin >> n >> m >> k >> s;
	for (int i = 1 ; i <= n ; i++)
	{
		cin >> a[i];
		got[a[i]].push_back(i);
	}
	for (int i = 1 ; i <= m ; i++)
	{
		int u , v;
		cin >> u >> v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	for (int i = 1 ; i <= k ; i++)
	{
		ruler.clear();
		pre = 0;
		for (int e = 0 ; e < got[i].size() ; e++)
		{
			ruler.push_back(got[i][e]);
			ok[got[i][e]] = i;
		}
		bfs(i , 0);
	}
	for (int i = 1 ; i <= n ; i++)
	{
		sort(res[i].begin() , res[i].end());
		long long kq = 0;
		for (int e = 0 ; e < s ; e++)
		{
			kq += res[i][e];
		}
		cout <<kq<<" ";
	}
}


#ifndef OUUAN
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#endif
#include<bits/stdc++.h>

//#define int LoveLive
//#define FAST_IOSTREAM 1

#define For(i,l,r)for(int i=(l),i##end=(r);i<=i##end;++i)
#define FOR(i,r,l)for(int i=(r),i##end=(l);i>=i##end;--i)
#define SON(i,u)for(int i=head[u];i;i=nxt[i])
#define ms(a,x)memset(a,x,sizeof(a))
#define fi first
#define se second
#define pb emplace_back
#define pq priority_queue
#define isinf(x)(x>=INF?-1:x)
#define y1 why_is_there_a_function_called_y1
#define DEBUG(x)cerr<<(#x)<<":"<<x<<endl
using namespace std;
typedef long long LoveLive;typedef pair<int,int>pii;typedef vector<int>vi;
#ifdef int
const int INF=0x3f3f3f3f3f3f3f3fll;
#else
const int INF=0x3f3f3f3f;
#endif
const double eps=1e-9;mt19937 rng(chrono::steady_clock::now().time_since_epoch().
count());int randint(int l,int r){int out=rng()%(r-l+1)+l;return out>=l?out:out+
r-l+1;}
#ifdef FAST_IOSTREAM
#define br cout<<'\n'
#define sp cout<<' '
long long read(){long long x;cin>>x;return x;}template<typename T>void read(T&x){
cin>>x;}template<typename T>void write(const T&x){cout<<x;}
#else
#define br putchar('\n')
#define sp putchar(' ')
template<typename T>typename enable_if<!is_integral<T>::value,void>::type read(T
&x){cin>>x;}long long read(){char c;long long out=0,f=1;for(c=getchar();!isdigit
(c)&&c!='-';c=getchar());if(c=='-'){f=-1;c=getchar();}for(;isdigit(c);c=getchar())
out=(out<<3)+(out<<1)+c-'0';return out*f;}template<typename T>typename enable_if
<is_integral<T>::value,T>::type read(T&x){char c;T f=1;x=0;for(c=getchar();!isdigit
(c)&&c!='-';c=getchar());if(c=='-'){f=-1;c=getchar();}for(;isdigit(c);c=getchar())
x=(x<<3)+(x<<1)+c-'0';return x*=f;}char read(char&x){for(x=getchar();isspace(x);
x=getchar());return x;}double read(double&x){scanf("%lf",&x);return x;}template<
typename T>typename enable_if<!is_integral<T>::value,void>::type write(const T&x
){cout<<x;}template<typename T>typename enable_if<is_integral<T>::value,void>::type
write(const T&x){if(x<0){putchar('-');write(-x);return;}if(x>9)write(x/10);putchar
(x%10+'0');}void write(const char&x){putchar(x);}void write(const double&x){printf
("%.10lf",x);}
#endif
template<typename T,typename...Args>void read(T&x,Args&...args){read(x);read(args
...);}template<typename OutputIt,typename=typename enable_if<is_same<output_iterator_tag
,typename iterator_traits<OutputIt>::iterator_category>::value||(
is_base_of<forward_iterator_tag,typename iterator_traits<OutputIt>::iterator_category>::value
&&!is_const<OutputIt>::value)>::type>void read(OutputIt __first,OutputIt __last){for(;__first
!=__last;++__first)read(*__first);}template<typename InputIt,typename=typename enable_if
<is_base_of<input_iterator_tag,typename iterator_traits<InputIt>::iterator_category
>::value>::type>void wts(InputIt __first,InputIt __last){bool isFirst=true;for(;
__first!=__last;++__first){if(isFirst)isFirst=false;else sp;write(*__first);}br;}
template<typename InputIt,typename=typename enable_if<is_base_of<input_iterator_tag
,typename iterator_traits<InputIt>::iterator_category>::value>::type>void wtb(InputIt
__first,InputIt __last){for(;__first!=__last;++__first){write(*__first);br;}}template
<typename T>void wts(const T&x){write(x);sp;}template<typename T>void wtb(const
T&x){write(x);br;}template<typename T>void wte(const T&x){write(x);exit(0);}template
<typename T,typename...Args>void wts(const T&x,Args...args){wts(x);wts(args...);}
template<typename T,typename...Args>void wtb(const T&x,Args...args){wts(x);wtb(args
...);}template<typename T,typename...Args>void wte(const T&x,Args...args){wts(x);
wte(args...);}template<typename T>inline bool up(T&x,const T&y){return x<y?x=y,1
:0;}template<typename T>inline bool dn(T&x,const T&y){return y<x?x=y,1:0;}

const int N = 100010;
const int mod = 1000000007;

int head[N], nxt[N << 1], to[N << 1], cnt;
int n, m, k, s, a[N], dis[N][105];
queue<int> q;

void add(int u, int v)
{
	nxt[++cnt] = head[u];
	head[u] = cnt;
	to[cnt] = v;
}

signed main()
{
#ifdef FAST_IOSTREAM
	cin.sync_with_stdio(false);
	cin.tie(0);
#endif

	read(n, m, k, s);

	For (i, 1, n) read(a[i]);

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

	ms(dis, 0x3f);

	For (i, 1, k)
	{
		For (u, 1, n)
		{
			if (a[u] == i)
			{
				dis[u][i] = 0;
				q.push(u);
			}
		}

		while (!q.empty())
		{
			int u = q.front();
			q.pop();
			SON (j, u)
			{
				int v = to[j];
				if (dn(dis[v][i], dis[u][i] + 1)) q.push(v);
			}
		}
	}

	For (i, 1, n)
	{
		nth_element(dis[i] + 1, dis[i] + s, dis[i] + k + 1);
		int ans = 0;
		For (j, 1, s) ans += dis[i][j];
		wts(ans);
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;

int main(){

  //986A - Falta optimizar .. O(n^2)
  int n,m,k,s;
  cin>>n>>m>>k>>s;
  vector<int> val(n);
  vector< vector<int> > pos(n); //posiciones lista-adya
  for(int i=0; i<n; i++){
    cin>>val[i];
  }
  for(int i=0; i<m; i++){
    int a,b; cin>>a>>b;
    pos[a-1].push_back(b-1);
    pos[b-1].push_back(a-1);
  }

  for(int i=0; i<n; i++){
    queue<int> q;
    vector<int> vis(n,0); vis[i]=1; //DP-lenght
    for(int j=0; j<pos[i].size(); j++){ //iniciar cola y DP-lenght
      q.push(pos[i][j]);
      vis[pos[i][j]] = 1;
    }
    int ans = 0;
    vector<int> sett; //set goods
    sett.push_back(val[i]);
    int tam = sett.size();
    while(tam<s){
      int temp = q.front();
      sett.push_back(val[temp]);
      for(int j=0; j<pos[temp].size(); j++){
	int in = pos[temp][j];
	if(vis[in]==0){
	  q.push(in);
	  vis[in] = vis[temp]+1;
	}
      }
      auto it = unique(sett.begin(), sett.end());
      sett.resize(distance(sett.begin(), it));
      if(sett.size()-tam)
	ans += vis[temp]; //hubo variacion - aumentar
      q.pop();
      tam = sett.size();
    }
    cout<<ans<<" ";
  }

}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;

int main(){

  //986A
  int n,m,k,s;
  cin>>n>>m>>k>>s;
  vector<int> val(n);
  vector< vector<int> > pos(n);
  for(int i=0; i<n; i++){
    cin>>val[i];
  }
  for(int i=0; i<m; i++){
    int a,b; cin>>a>>b;
    pos[a-1].push_back(b-1);
    pos[b-1].push_back(a-1);
  }
  for(int i=0; i<n; i++){
    queue<int> q;
    vector<int> vis(n,0); vis[i]=1;
    for(int j=0; j<pos[i].size(); j++){
      q.push(pos[i][j]);
      vis[pos[i][j]] = 1;
    }
    int ans = 0;
    set<int> sett;
    sett.insert(val[i]);
    int tam = sett.size();
    while(tam<s){
      int temp = q.front();
      sett.insert(val[temp]);
      for(int j=0; j<pos[temp].size(); j++){
	int in = pos[temp][j];
	if(!vis[in]){
	  q.push(in);
	  vis[in] = vis[temp]+1;
	}
      }
      if(sett.size()-tam)
	ans += vis[temp];
      q.pop();
      tam = sett.size();
    }
    cout<<ans<<" ";
  }

}


#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

int n,m,k,s;
vector<int> val;
vector< vector<int> > pos;
vector< vector<int> > dis;

void bfs(int value){

  queue<int> q;
  vector<bool> visita(n,false);
  for(int i=0; i<n; i++){
    if(val[i]==(value+1)){
      visita[i]=true;
      q.push(i);
    }
  }
  while(!q.empty()){
    int temp = q.front();
    for(int j=0; j<pos[temp].size(); j++){
      int in = pos[temp][j];
      if(!visita[in]){
	visita[in]=true;
	dis[in][value] = dis[temp][value] + 1;
	q.push(in);
      }
    }
    q.pop();
  }

}

int main(){

  cin>>n>>m>>k>>s;
  val = vector<int>(n);
  pos = vector< vector<int> > (n);
  dis = vector< vector<int> > (n, vector<int> (k,0));

  for(int i=0; i<n; i++){
    cin>>val[i];
  }
  for(int i=0; i<m; i++){
    int a,b;
    cin>>a>>b;
    pos[a-1].push_back(b-1);
    pos[b-1].push_back(a-1);
  }

  for(int i=0; i<k; i++){
    bfs(i);
  }

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

}


// https://codeforces.com/contest/986/problem/A

#include <bits/stdc++.h>
using namespace std;
#define watch(x) cerr << (#x) << " is " << (x) << endl;
#define endl '\n'
#define int long long
const int maxn = 100500;
const int maxk = 105;
const int INF = INT_MAX-100;
set<int> G[maxn];
int dis[maxk][maxn];
int type[maxn];

signed main() {
    ios::sync_with_stdio(0);
    cin.sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0; i < maxk; i++) {
        for(int j = 0; j < maxn; j++) {
            dis[i][j] = INF;
        }
    }

    int n, m, k, s;
    cin >> n >> m >> k >> s;

    for(int i = 1; i <= n; i++) {
        cin >> type[i];
    }

    for(int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;

        G[u].emplace(v);
        G[v].emplace(u);
    }

    for(int t = 1; t <= k; t++) {
        queue<int> Q;
        for(int i = 1; i <= n; i++) {
            if(type[i] == t) {
                Q.push(i);
                dis[t][i] = 0;
            }
        }

        while(!Q.empty()) {
            int S = Q.front(); Q.pop();
            for(int adj: G[S]) {
                if(dis[t][adj] > dis[t][S]+1) {
                    Q.push(adj);
                    dis[t][adj] = dis[t][S]+1;
                }
            }
        }
    }

    for(int i = 1; i <= n; i++) {
        vector<int> costs;
        for(int j = 1; j <= k; j++) {
            costs.emplace_back(dis[j][i]);
        }
        sort(costs.begin(), costs.end());

        int ans = 0;
        for(int j = 0; j < s; j++) {
            ans += costs[j];
        }

        cout << ans << " ";
    }
    cout << endl;
}


// https://codeforces.com/contest/986/problem/A

#include <bits/stdc++.h>
using namespace std;
#define watch(x) cerr << (#x) << " is " << (x) << endl;
#define endl '\n'
#define int long long
const int maxn = 100500;
const int maxk = 105;
const int INF = INT_MAX-100;
set<int> G[maxn];
int dis[maxk][maxn];
int type[maxn];

signed main() {
    ios::sync_with_stdio(0);
    cin.sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0; i < maxk; i++) {
        for(int j = 0; j < maxn; j++) {
            dis[i][j] = INF;
        }
    }

    int n, m, k, s;
    cin >> n >> m >> k >> s;

    for(int i = 1; i <= n; i++) {
        cin >> type[i];
    }

    for(int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;

        G[u].emplace(v);
        G[v].emplace(u);
    }

    for(int t = 1; t <= k; t++) {
        queue<int> Q;
        for(int i = 1; i <= n; i++) {
            if(type[i] == t) {
                Q.push(i);
                dis[t][i] = 0;
            }
        }

        while(!Q.empty()) {
            int S = Q.front(); Q.pop();
            for(int adj: G[S]) {
                if(dis[t][adj] >= dis[t][S]+1) {
                    Q.push(adj);
                    dis[t][adj] = dis[t][S]+1;
                }
            }
        }
    }

    for(int i = 1; i <= n; i++) {
        vector<int> costs;
        for(int j = 1; j <= k; j++) {
            costs.emplace_back(dis[j][i]);
        }
        sort(costs.begin(), costs.end());

        int ans = 0;
        for(int j = 0; j < s; j++) {
            ans += costs[j];
        }

        cout << ans << " ";
    }
    cout << endl;
}


// https://codeforces.com/contest/986/problem/A

#include <bits/stdc++.h>
using namespace std;
#define watch(x) cerr << (#x) << " is " << (x) << endl;
#define endl '\n'

const int maxn = 100500;
const int maxk = 105;
const int INF = INT_MAX-100;
set<int> G[maxn];
int dis[maxk][maxn];
int type[maxn];

signed main() {
    ios::sync_with_stdio(0);
    cin.sync_with_stdio(0);
    cin.tie(0);

    for(int i = 0; i < maxk; i++) {
        for(int j = 0; j < maxn; j++) {
            dis[i][j] = INF;
        }
    }

    int n, m, k, s;
    cin >> n >> m >> k >> s;

    for(int i = 1; i <= n; i++) {
        cin >> type[i];
    }

    for(int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;

        G[u].emplace(v);
        G[v].emplace(u);
    }

    for(int t = 1; t <= k; t++) {
        queue<int> Q;
        for(int i = 1; i <= n; i++) {
            if(type[i] == t) {
                Q.push(i);
                dis[t][i] = 0;
            }
        }

        while(!Q.empty()) {
            int S = Q.front(); Q.pop();
            for(int adj: G[S]) {
                if(dis[t][adj] >= dis[t][S]+1) {
                    Q.push(adj);
                    dis[t][adj] = dis[t][S]+1;
                }
            }
        }
    }

    for(int i = 1; i <= n; i++) {
        vector<int> costs;
        for(int j = 1; j <= k; j++) {
            costs.emplace_back(dis[j][i]);
        }
        sort(costs.begin(), costs.end());

        int ans = 0;
        for(int j = 0; j < s; j++) {
            ans += costs[j];
        }

        cout << ans << " ";
    }
    cout << endl;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (vector<int>src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    FOR(i,0,src.size()){
        q.push_back(mp(src[i],0));
        tab[src[i]]=0;
    }
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(tab[roads[cur][i]]>cur_pos+1){
                q.push_back(mp(roads[cur][i],cur_pos+1));
                tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        bfs(goods[i],roads,tab);
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        nth_element(ans[i].begin(),ans[i].begin()+s,ans[i].begin()+k);
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (int src,vector<int>roads[],vector<int>goods){
    bool vis[n];
    memset(vis,0,n);
    vis[src]=true;
    list<ipair>q;
    q.push_back(mp(src,0));
    vector<int>tab(k,INF);
    tab[goods[src]]=0;
    while(!q.empty()){
        int cur=q.front().first;
        int cur_cost=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(!vis[roads[cur][i]]){
                vis[roads[cur][i]]=true;
                if(tab[goods[roads[cur][i]]]>cur_cost+1)
                    tab[goods[roads[cur][i]]]=cur_cost+1;
                q.push_back(mp(roads[cur][i],cur_cost+1));
            }
        }
    }

    sort(tab.begin(),tab.end());
    int res=0;
    FOR(i,0,s){
        res+=tab[i];
    }
    return res;
}
int main()
{
    cin>>n>>m>>k>>s;
    vector<int>goods(n);
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[i]=a;
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    FOR(i,0,n){
        cout<<bfs(i,roads,goods)<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (int src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    q.push_back(mp(src,0));
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(!vis[roads[cur][i]]){
                vis[roads[cur][i]]=true;
                q.push_back(mp(roads[cur][i],cur_pos+1));
                if(tab[roads[cur][i]]>cur_pos+1)
                    tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        FOR(j,0,goods[i].size()){
            tab[goods[i][j]]=0;
            bfs(goods[i][j],roads,tab);
        }
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        sort(ans[i].begin(),ans[i].end());
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (vector<int>src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    FOR(i,0,src.size()){
        q.push_back(mp(src[i],0));
        tab[src[i]]=0;
    }
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(tab[roads[cur][i]]>cur_pos+1){
                q.push_back(mp(roads[cur][i],cur_pos+1));
                tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        bfs(goods[i],roads,tab);
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        sort(ans[i].begin(),ans[i].end());
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (vector<int>src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    FOR(i,0,src.size()){
        q.push_back(mp(src[i],0));
        tab[src[i]]=0;
    }
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(!vis[roads[cur][i]]){
                vis[roads[cur][i]]=true;
                q.push_back(mp(roads[cur][i],cur_pos+1));
                if(tab[roads[cur][i]]>cur_pos+1)
                    tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        bfs(goods[i],roads,tab);
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        nth_element(ans[i].begin(),ans[i].begin()+s,ans[i].begin()+k);
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (vector<int>src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    FOR(i,0,src.size()){
        q.push_back(mp(src[i],0));
        tab[src[i]]=0;
    }
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(!vis[roads[cur][i]]){
                vis[roads[cur][i]]=true;
                q.push_back(mp(roads[cur][i],cur_pos+1));
                if(tab[roads[cur][i]]>cur_pos+1)
                    tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        bfs(goods[i],roads,tab);
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        sort(ans[i].begin(),ans[i].end());
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define FOR(i,a,n) for(long long i=a;i<n;++i)
#define FORR(i,a,n) for(long long i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define ll long long
#define ipair pair<int,int>
#define vipair vector<ipair>
#define INF 0x3f3f3f3f

using namespace std;
int n,m,k,s;
int bfs (vector<int>src,vector<int>roads[],vector<int>&tab){
    bool vis[n];
    memset(vis,0,n);
    list<ipair>q;
    FOR(i,0,src.size()){
        q.push_back(mp(src[i],0));
        tab[src[i]]=0;
    }
    while(!q.empty()){
        int cur=q.front().first;
        int cur_pos=q.front().second;
        q.pop_front();
        FOR(i,0,roads[cur].size()){
            if(tab[roads[cur][i]]>cur_pos+1){
                q.push_back(mp(roads[cur][i],cur_pos+1));
                tab[roads[cur][i]]=cur_pos+1;
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k>>s;
    vector<int>goods[k];
    vector<int>roads[n];
    bool vis[n];
    FOR(i,0,n){
        int a;
        cin>>a;
        a--;
        goods[a].pb(i);
    }
    FOR(i,0,m){
        int a,b;
        cin>>a>>b;
        a--,b--;
        roads[a].pb(b);
        roads[b].pb(a);
    }
    vector<int>ans[n];
    FOR(i,0,k){
        vector<int>tab(n,INF);
        bfs(goods[i],roads,tab);
        FOR(j,0,tab.size()){
            ans[j].pb(tab[j]);
        }
    }
    FOR(i,0,n){
        int res=0;
        nth_element(ans[i].begin(),ans[i].begin()+s,ans[i].begin()+k);
        FOR(j,0,s){
            res+=ans[i][j];
        }
        cout<<res<<" ";
    }
    cout<<endl;
    return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define INF 10000000

using namespace std;

int dst[100002][102];//for each town, distance to k-th good
int a[100002];
vector<int> twns[101];//list of towns for the i-th good
vector<int> nei[100002];

vector<int> dists[100002];//VECTOR of distances to the lowest good stores.

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int N,M,K,S;cin>>N>>M>>K>>S;
  for(int i = 1; i <= N; i++)
  {
    cin >> a[i];
    twns[a[i]].pb(i);//towns selling a[i] item include town i.
    for(int k = 1; k <= K; k++)
    {
      dst[i][k] = INF;
    }
  }
  for(int i = 1; i <= M; i++)
  {
    int u,v;
    cin>>u>>v;
    nei[u].pb(v);
    nei[v].pb(u);
  }
  //precompute shortest path from less than 100 types
  for(int i = 1; i <= K; i++)
  {
    priority_queue<pii, vector<pii>, greater<pii> > q; //min pq for cities (distance, town_id)
    bool vis[100001];
    for(int j = 0; j <= N; j++)
    {
      vis[j] = false;
    }
    for(int t : twns[i]) //all towns selling i_th itemm set distance to 0.
    {
      q.push(mp(0,t));
    }
    while(!q.empty())
    {
      pii town = q.top();
      q.pop();

      int dist = town.first;
      int id = town.second;
      vis[id] = true;
      dst[id][i] = min(dst[id][i],dist);

      for(int n : nei[id])
      {
        if(vis[n]) continue;
        q.push(mp(dist + 1, n));
      }
    }
  }
  //convert to vector..
  for(int i = 1; i <= N; i++)
  {
    for(int k = 1; k <= K; k++)
    {
      dists[i].push_back(dst[i][k]);
    }
    sort(dists[i].begin(), dists[i].end());
  }
  //query
  for(int i = 1; i <= N; i++)
  {
    int d = 0;
    for(int j = 0; j < S; j++)
    {
      d += dists[i][j];
    }
    cout << d << ' ';
  }
  cout << '\n';

  return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define INF 10000000

using namespace std;

int dst[100002][102];//for each town, distance to k-th good
int a[100002];
vector<int> twns[101];//list of towns for the i-th good
vector<int> nei[100002];

vector<int> dists[100002];//VECTOR of distances to the lowest good stores.

int main()
{
  int N,M,K,S;cin>>N>>M>>K>>S;
  for(int i = 1; i <= N; i++)
  {
    cin >> a[i];
    twns[a[i]].pb(i);//towns selling a[i] item include town i.
    for(int k = 1; k <= K; k++)
    {
      dst[i][k] = INF;
    }
  }
  for(int i = 1; i <= M; i++)
  {
    int u,v;
    cin>>u>>v;
    nei[u].pb(v);
    nei[v].pb(u);
  }
  //precompute shortest path from less than 100 types
  for(int i = 1; i <= K; i++)
  {
    priority_queue<pii, vector<pii>, greater<pii> > q; //min pq for cities (distance, town_id)
    bool vis[100001];
    for(int j = 0; j <= N; j++)
    {
      vis[j] = false;
    }
    for(int t : twns[i]) //all towns selling i_th itemm set distance to 0.
    {
      q.push(mp(0,t));
    }
    while(!q.empty())
    {
      pii town = q.top();
      q.pop();

      int dist = town.first;
      int id = town.second;
      vis[id] = true;
      dst[id][i] = min(dst[id][i],dist);

      for(int n : nei[id])
      {
        if(vis[n]) continue;
        q.push(mp(dist + 1, n));
      }
    }
  }
  //convert to vector..
  for(int i = 1; i <= N; i++)
  {
    for(int k = 1; k <= K; k++)
    {
      dists[i].push_back(dst[i][k]);
    }
    sort(dists[i].begin(), dists[i].end());
  }
  //query
  for(int i = 1; i <= N; i++)
  {
    int d = 0;
    for(int j = 0; j < S; j++)
    {
      d += dists[i][j];
    }
    cout << d << ' ';
  }
  cout << '\n';

  return 0;
}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define INF 10000000

using namespace std;

int dst[100002][102];//for each town, distance to k-th good
int a[100002];
vector<int> twns[101];//list of towns for the i-th good
vector<int> nei[100002];

vector<int> dists[100002];//VECTOR of distances to the lowest good stores.

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int N,M,K,S;cin>>N>>M>>K>>S;
  for(int i = 1; i <= N; i++)
  {
    cin >> a[i];
    twns[a[i]].pb(i);//towns selling a[i] item include town i.
    for(int k = 1; k <= K; k++)
    {
      dst[i][k] = INF;
    }
  }
  for(int i = 1; i <= M; i++)
  {
    int u,v;
    cin>>u>>v;
    nei[u].pb(v);
    nei[v].pb(u);
  }
  //precompute shortest path from less than 100 types
  for(int i = 1; i <= K; i++)
  {
    queue<pii> q; //min pq for cities (distance, town_id)
    bool vis[100001];
    for(int j = 0; j <= N; j++)
    {
      vis[j] = false;
    }
    for(int t : twns[i]) //all towns selling i_th itemm set distance to 0.
    {
      q.push(mp(0,t));
    }
    while(!q.empty())
    {
      pii town = q.front();
      q.pop();

      int dist = town.first;
      int id = town.second;
      vis[id] = true;
      dst[id][i] = min(dst[id][i],dist);

      for(int n : nei[id])
      {
        if(vis[n]) continue;
        q.push(mp(dist + 1, n));
      }
    }
  }
  //convert to vector..
  for(int i = 1; i <= N; i++)
  {
    for(int k = 1; k <= K; k++)
    {
      dists[i].push_back(dst[i][k]);
    }
    sort(dists[i].begin(), dists[i].end());
  }
  //query
  for(int i = 1; i <= N; i++)
  {
    int d = 0;
    for(int j = 0; j < S; j++)
    {
      d += dists[i][j];
    }
    cout << d << ' ';
  }
  cout << '\n';

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
int t[100001];
struct line
{
	int s,t;
	int next;
}a[200001];
int head[100001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[100001];
int dis[100001][101];
queue<int> Q;
inline bool bfs(int x,int d)
{
//	memset(v,false,sizeof(v));
	dis[x][d]=0;
	Q.push(x);
	while(!Q.empty())
	{
		int dd=Q.front();
		Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					Q.push(t);
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	int i,j;
	for(i=1;i<=n;i++)
		scanf("%d",&t[i]);
	int ss,tt;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&ss,&tt);
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
		bfs(i,t[i]);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
		sort(dis[i]+1,dis[i]+1+k);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d ",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[6000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,6000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    char ch=nc();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
struct th
{
	int x,p;
	bool operator <(th y) const
	{
		return x<y.p;
	}
}t[1000001];
struct line
{
	int s,t;
	int next;
}a[2000001];
int head[1000001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[1000001];
int dis[1000001][101];
//int Q[2000001];
queue<int> Q;
inline bool bfs(int d)
{
//	memset(v,false,sizeof(v));
//	dis[x][d]=0;
//	int l=1,r=1;
//	Q.push(x);
//	Q[r]=x;
	//v[x]=true;
	while(!Q.empty())
	{
		int dd=Q.front();
	//	int dd=Q[l];
	//	l++;
		Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
				//	if(!v[t])
				//	{
				//		v[t]=true;
						Q.push(t);
				//		r++;
				//		Q[r]=t;
				//	}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
//	scanf("%d%d%d%d",&n,&m,&k,&s);
	n=read();
	m=read();
	k=read();
	s=read();
	int i,j;
	for(i=1;i<=n;i++)
	{
		//scanf("%d",&t[i]);
		t[i].x=read();
		t[i].p=i;
	}
	int ss,tt;
	for(i=1;i<=m;i++)
	{
	//	scanf("%d%d",&ss,&tt);
		ss=read();
		tt=read();
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	sort(t+1,t+1+n);
	for(i=1;i<=n;i++)
	{
		if(t[i].x!=t[i-1].x)
		{
			dis[i][t[i].x]=0;
			Q.push(i);
		}
		bfs(t[i-1].x);
	}
	bfs(t[i-1].x);
		//assert(i<=200);
//	}
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[6000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,6000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    char ch=nc();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
int t[1000001];
struct line
{
	int s,t;
	int next;
}a[2000001];
int head[1000001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[1000001];
int dis[1000001][101];
int Q[2000001];
inline bool bfs(int x,int d)
{
	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	v[x]=true;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					if(!v[t])
					{
						v[t]=true;
				//	Q.push(t);
						r++;
						Q[r]=t;
					}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
//	scanf("%d%d%d%d",&n,&m,&k,&s);
	n=read();
	m=read();
	k=read();
	s=read();
	int i,j;
	for(i=1;i<=n;i++)
		//scanf("%d",&t[i]);
		t[i]=read();
	int ss,tt;
	for(i=1;i<=m;i++)
	{
	//	scanf("%d%d",&ss,&tt);
		ss=read();
		tt=read();
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
	{
		bfs(i,t[i]);
		assert(i<=80000);
	}
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int t[100001];
struct line
{
	int s,t;
	int next;
}a[200001];
int head[100001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[100001];
int dis[100001][101];
int Q[200001];
inline bool bfs(int x,int d)
{
//	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
				//	Q.push(t);
					r++;
					Q[r]=t;
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	int i,j;
	for(i=1;i<=n;i++)
		scanf("%d",&t[i]);
	int ss,tt;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&ss,&tt);
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
		bfs(i,t[i]);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[6000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,6000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    char ch=nc();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
int t[1000001];
struct line
{
	int s,t;
	int next;
}a[2000001];
int head[1000001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[1000001];
int dis[1000001][101];
int Q[2000001];
inline bool bfs(int x,int d)
{
	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	v[x]=true;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					if(!v[t])
					{
						v[t]=true;
				//	Q.push(t);
						r++;
						Q[r]=t;
					}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
//	scanf("%d%d%d%d",&n,&m,&k,&s);
	n=read();
	m=read();
	k=read();
	s=read();
	int i,j;
	for(i=1;i<=n;i++)
		//scanf("%d",&t[i]);
		t[i]=read();
	int ss,tt;
	for(i=1;i<=m;i++)
	{
	//	scanf("%d%d",&ss,&tt);
		ss=read();
		tt=read();
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
	{
		bfs(i,t[i]);
		assert(i<=10000);
	}
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[6000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,6000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    char ch=nc();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
int t[100001];
struct line
{
	int s,t;
	int next;
}a[200001];
int head[100001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[100001];
int dis[100001][101];
int Q[200001];
inline bool bfs(int x,int d)
{
	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	v[x]=true;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					if(!v[t])
					{
						v[t]=true;
				//	Q.push(t);
						r++;
						Q[r]=t;
					}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
//	scanf("%d%d%d%d",&n,&m,&k,&s);
	n=read();
	m=read();
	s=read();
	k=read();
	int i,j;
	for(i=1;i<=n;i++)
		//scanf("%d",&t[i]);
		t[i]=read();
	int ss,tt;
	for(i=1;i<=m;i++)
	{
	//	scanf("%d%d",&ss,&tt);
		ss=read();
		tt=read();
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
		bfs(i,t[i]);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[6000000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,6000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    char ch=nc();int sum=0;
    while(!(ch>='0'&&ch<='9'))ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return sum;
}
int t[1000001];
struct line
{
	int s,t;
	int next;
}a[2000001];
int head[1000001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[1000001];
int dis[1000001][101];
int Q[2000001];
inline bool bfs(int x,int d)
{
	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	v[x]=true;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					if(!v[t])
					{
						v[t]=true;
				//	Q.push(t);
						r++;
						Q[r]=t;
					}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
//	scanf("%d%d%d%d",&n,&m,&k,&s);
	n=read();
	m=read();
	k=read();
	s=read();
	int i,j;
	for(i=1;i<=n;i++)
		//scanf("%d",&t[i]);
		t[i]=read();
	int ss,tt;
	for(i=1;i<=m;i++)
	{
	//	scanf("%d%d",&ss,&tt);
		ss=read();
		tt=read();
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
		bfs(i,t[i]);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int t[100001];
struct line
{
	int s,t;
	int next;
}a[200001];
int head[100001];
int edge;
inline void add(int s,int t)
{
	a[edge].next=head[s];
	head[s]=edge;
	a[edge].s=s;
	a[edge].t=t;
}
bool v[100001];
int dis[100001][101];
int Q[200001];
inline bool bfs(int x,int d)
{
	memset(v,false,sizeof(v));
	dis[x][d]=0;
	int l=1,r=1;
	//Q.push(x);
	Q[r]=x;
	v[x]=true;
	while(l<=r)
	{
	//	int dd=Q.front();
		int dd=Q[l];
		l++;
	//	Q.pop();
		int i;
		for(i=head[dd];i!=0;i=a[i].next)
		{
			int t=a[i].t;
		//	if(!v[t])
		//	{
				if(dis[dd][d]+1<dis[t][d])
				{
					dis[t][d]=dis[dd][d]+1;
					if(!v[t])
					{
						v[t]=true;
				//	Q.push(t);
						r++;
						Q[r]=t;
					}
				}
		//	}
		}
	}
}
int main()
{
	int n,m,s,k;
	scanf("%d%d%d%d",&n,&m,&k,&s);
	int i,j;
	for(i=1;i<=n;i++)
		scanf("%d",&t[i]);
	int ss,tt;
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&ss,&tt);
		edge++;
		add(ss,tt);
		edge++;
		add(tt,ss);
	}
	memset(dis,127/3,sizeof(dis));
	for(i=1;i<=n;i++)
		bfs(i,t[i]);
/*	for(i=1;i<=n;i++)
	{
		for(j=1;j<=k;j++)
			printf("%d ",dis[i][j]);
		printf("\n");
	}*/
	for(i=1;i<=n;i++)
	{
		sort(dis[i]+1,dis[i]+1+k);
		int sum=0;
		for(j=1;j<=s;j++)
			sum+=dis[i][j];
		printf("%d\n",sum);
	}
	return 0;
}