#include <bits/stdc++.h>
using namespace std;
const int maxN = 5e6 + 10;
const int N = 1e5 + 10;
int n, m, d, c = 0;
int p[maxN], f[maxN];
vector<int> g[maxN], x, x1;
vector<pair<int, int> > adj;
bool mark[maxN], mark1[N];
string sch[N];
void dfs1(int u) {
  mark[u] = 1;
  for (auto v : g[u]) {
    if (!mark[v]) dfs1(v);
  }
  x.push_back(u);
}
void dfs2(int u) {
  mark[u] = 1;
  p[u] = c;
  if (sch[u / d][u % d] == '1' && mark1[u / d] == 0) {
    ++f[c];
    mark1[u / d] = 1;
    x1.push_back(u / d);
  }
  for (auto v : g[u]) {
    if (!mark[v]) dfs2(v);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie();
  cout.tie();
  cin >> n >> m >> d;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    --u, --v;
    adj.push_back({u, v});
    for (int j = 0; j < d; ++j) {
      g[u * d + j].push_back(v * d + (j + 1) % d);
    }
  }
  for (int i = 0; i < n; ++i) cin >> sch[i];
  for (int i = 0; i < n * d; ++i)
    if (!mark[i]) dfs1(i);
  for (int i = 0; i < maxN; ++i) g[i].clear();
  for (auto i : adj) {
    for (int j = 0; j < d; ++j) {
      int u = i.first * d + j;
      int v = i.second * d + ((j + 1) % d);
      g[v].push_back(u);
    }
  }
  memset(mark, 0, sizeof(mark));
  reverse(x.begin(), x.end());
  for (auto i : x) {
    if (!mark[i]) {
      for (auto v : x1) mark1[v] = 0;
      x1.clear();
      dfs2(i);
      ++c;
    }
  }
  for (int i = 0; i < maxN; ++i) g[i].clear();
  for (auto i : adj) {
    for (int j = 0; j < d; ++j) {
      int u = i.first * d + j;
      int v = i.second * d + ((j + 1) % d);
      if (p[u] != p[v]) g[p[u]].push_back(p[v]);
    }
  }
  for (int i = c - 1; i >= 0; --i) {
    int cnt = 0;
    for (auto j : g[i]) cnt = max(cnt, f[j]);
    f[i] += cnt;
  }
  cout << f[p[0]];
}
