#include <bits/stdc++.h>
using namespace std;
const int MX = 5 * 1e6 + 10, MX2 = 1e5 + 10;
vector<int> g[MX];
vector<pair<int, int> > edge;
int used[MX], col[MX], comp[MX], val[MX], dp[MX];
int d;
vector<int> ord;
void dfs1(int v) {
  used[v] = 1;
  for (int u : g[v])
    if (!used[u]) dfs1(u);
  ord.push_back(v);
}
void dfs2(int v, int k) {
  comp[v] = k;
  if (used[v / d] != k) val[k] += col[v];
  if (col[v] == 1) used[v / d] = k;
  for (int u : g[v])
    if (comp[u] == -1) dfs2(u, k);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m >> d;
  int a, b;
  for (int i = 0; i < m; i++) {
    cin >> a >> b;
    a--;
    b--;
    edge.push_back({a, b});
    for (int t = 0; t < d; t++) g[a * d + t].push_back(b * d + (t + 1) % d);
  }
  string s;
  for (int i = 0; i < n; i++) {
    cin >> s;
    for (int t = 0; t < d; t++) col[i * d + t] = s[t] - '0';
  }
  int N = n * d;
  for (int i = 0; i < N; i++) used[i] = 0;
  for (int i = 0; i < N; i++)
    if (!used[i]) dfs1(i);
  for (int i = 0; i < N; i++) {
    comp[i] = -1;
    used[i] = -1;
    val[i] = 0;
    g[i].clear();
  }
  for (auto p : edge) {
    a = p.first;
    b = p.second;
    for (int t = 0; t < d; t++) g[b * d + (t + 1) % d].push_back(a * d + t);
  }
  int ln = 0;
  reverse(ord.begin(), ord.end());
  for (int v : ord)
    if (comp[v] == -1) {
      dfs2(v, ln);
      ln++;
    }
  for (int i = 0; i < N; i++) g[i].clear();
  for (auto p : edge) {
    a = p.first;
    b = p.second;
    for (int t = 0; t < d; t++) {
      int aa = a * d + t, bb = b * d + (t + 1) % d;
      if (comp[aa] != comp[bb]) g[comp[aa]].push_back(comp[bb]);
    }
  }
  for (int i = ln - 1; i >= 0; i--) {
    dp[i] = val[i];
    int mx = 0;
    for (int j : g[i]) mx = max(mx, dp[j]);
    dp[i] += mx;
  }
  cout << dp[comp[0]] << "\n";
  return 0;
}
