#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e18;
int n,m,k;
vector<int> con[50005];
bool iss[50005];
int init[50005];
int rez[50005];
int dist1[50005];
void calc_closest1()
{
deque<int> dq;
for(int i=1;i<=n;i++)
{
if(iss[i])
{
dist1[i] = 0;
dq.push_back(i);
}
else
{
dist1[i] = INF;
}
}
while(!dq.empty())
{
int nod = dq.front();
dq.pop_front();
for(int adj:con[nod])
{
if(dist1[adj] > dist1[nod] + 1)
{
dist1[adj] = dist1[nod] + 1;
dq.push_back(adj);
}
}
}
}
int best11[50005];
void calc_11()
{
deque<int> dq;
for(int i=1;i<=n;i++)
{
best11[i] = INF;
if(!iss[i])
continue;
bool bun = 0;
for(int adj:con[i])
if(iss[adj])
bun = 1;
if(bun)
{
best11[i] = -1;
dq.push_back(i);
}
}
while(!dq.empty())
{
int nod = dq.front();
dq.pop_front();
for(int adj:con[nod])
{
if(iss[adj])
{
if(best11[adj] > best11[nod])
{
best11[adj] = best11[nod];
dq.push_front(adj);
}
}
else
{
if(best11[adj] > best11[nod] + 1)
{
best11[adj] = best11[nod] + 1;
dq.push_back(adj);
}
}
}
}
for(int i=1;i<=n;i++)
if(iss[i] && best11[i] < INF)
best11[i]++;
}
int direct[50005];
void calc_directly()//see if we can reach some nodes without going through stop nodes
{
deque<int> dq;
for(int i=1;i<=n;i++)
direct[i] = INF;
direct[init[1]] = 0;
dq.push_back(init[1]);
while(!dq.empty())
{
int nod = dq.front();
dq.pop_front();
for(int adj:con[nod])
{
if(!iss[adj] && direct[adj] > direct[nod] + 1)
{
direct[adj] = direct[nod] + 1;
dq.push_back(adj);
}
}
}
for(int i=1;i<=n;i++)
for(int adj:con[i])
rez[adj] = min(rez[adj], direct[i] + 1);
for(int i=1;i<=n;i++)
rez[i] = min(rez[i], direct[i]);
}
int dist[50005];
void calc_dist(int cost_first, int stop_cost)//optimize with 2 queues instead of a pq-------------------------------------------
{
for(int i=1;i<=n;i++)
dist[i] = INF;
for(int i=1;i<=n;i++)
{
if(direct[i] == INF)
continue;
for(int adj:con[i])
{
if(iss[adj])
{
dist[adj] = min(dist[adj], cost_first + (direct[i] + 1));
}
}
}
priority_queue<pair<int,int>> pq;
for(int i=1;i<=n;i++)
if(dist[i] < INF)
pq.push({-dist[i], i});
while(!pq.empty())
{
int nod = pq.top().second;
int cdist = -pq.top().first;
pq.pop();
if(dist[nod] != cdist)
continue;
for(int adj:con[nod])
{
if(iss[adj])
{
rez[adj] = min(rez[adj], dist[nod] + 1);
if(dist[adj] > dist[nod] + stop_cost)
{
dist[adj] = dist[nod] + stop_cost;
pq.push({-dist[adj], adj});
}
}
else
{
if(dist[adj] > dist[nod] + 1)
{
dist[adj] = dist[nod] + 1;
pq.push({-dist[adj], adj});
}
}
}
}
for(int i=1;i<=n;i++)
rez[i] = min(rez[i], dist[i]);
}
signed main()
{
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n>>m>>k;
int u,v;
for(int i=1;i<=m;i++)
{
cin>>u>>v;
con[u].push_back(v);
con[v].push_back(u);
}
string s;
cin>>s;
assert(s.size() == n);
for(int i=0;i<s.size();i++)
{
if(s[i] == '1')
iss[i+1] = 1;
else
iss[i+1] = 0;
}
for(int i=1;i<=k;i++)
cin>>init[i];
for(int i=1;i<=n;i++)
rez[i] = INF;
calc_directly();
calc_11();
calc_closest1();
for(int i=1;i<=n;i++)
if(dist1[i] == 0)
dist1[i] = 2;
//for(int i=1;i<=n;i++) cerr<<i<<": "<<dist1[i]<<" "<<best11[i]<<" dist1 & best11\n";
//fix the nr of people that use 11------------------------------------
vector<pair<int,int>> ord;
for(int i=2;i<=k;i++)
{
ord.push_back({best11[init[i]] - dist1[init[i]], init[i]});
}
sort(ord.begin(), ord.end());
for(int nr11=0;nr11<=min((int)1000,k-1);nr11++)
{
int cost_first = 0, stop_cost = 1;
bool good = 1;
for(int i=0;i<nr11;i++)//take these as 11
{
int x = ord[i].second;
if(best11[x] == INF)
{
good = 0;
break;
}
cost_first += best11[x] + 1;
stop_cost += 1;
}
for(int i=nr11;i<ord.size();i++)//take these as 1
{
int x = ord[i].second;
if(dist1[x] == INF)
{
good = 0;
break;
}
cost_first += dist1[x];
stop_cost += 2;
}
if(good)
{
//cerr<<cost_first<<" "<<stop_cost<<" costs\n";
calc_dist(cost_first, stop_cost);
}
}
for(int i=1;i<=n;i++)
{
assert(rez[i] < INF);
cout<<rez[i]<<"\n";
}
return 0;
}