#include <bits/stdc++.h>
using namespace std;
template <typename G>
struct triple {
  G first, second, T;
};
vector<vector<int>> strongly_connected_components(const vector<vector<int>> &g,
                                                  int d) {
  int n = g.size();
  vector<vector<int>> scc;
  vector<int> second, B, I(n * d, -1), ord, edge(n * d, -1);
  auto run = [&]() {
    while (!ord.empty()) {
      int u = ord.back();
      ord.pop_back();
      if (edge[u] == -1) {
        B.push_back(I[u] = second.size());
        second.push_back(u);
      }
      int k = u / n;
      bool done = true;
      while (++edge[u] < g[u % n].size()) {
        int v = n * ((k + 1) % d) + g[u % n][edge[u]];
        if (!~I[v]) {
          ord.emplace_back(u);
          ord.emplace_back(v);
          done = false;
          break;
        } else
          while (I[v] < B.back()) B.pop_back();
      }
      if (done && I[u] == B.back()) {
        scc.push_back({});
        B.pop_back();
        while (I[u] < (int)second.size()) {
          scc.back().push_back(second.back());
          I[second.back()] = n * d + scc.size();
          second.pop_back();
        }
      }
    }
  };
  for (int u = 0; u < n; ++u)
    for (int j = 0; j < d; j++)
      if (!~I[n * j + u]) {
        ord.emplace_back(n * j + u);
        run();
      }
  return scc;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m, d;
  cin >> n >> m >> d;
  vector<vector<int>> g(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    g[x].push_back(y);
  }
  vector<string> h(n);
  for (auto &i : h) cin >> i;
  auto scc = strongly_connected_components(g, d);
  vector<bool> s(n * d);
  int sz = scc.size();
  vector<int> v(sz);
  for (int cc = 0; cc < scc.size(); cc++) {
    int cnt = 0;
    for (auto k : scc[cc]) {
      int i = k % n;
      int j = k / n;
      if (h[i][j] == '1') {
        cnt += (s[i] == false);
        s[i] = true;
      }
    }
    for (auto k : scc[cc]) {
      int i = k % n;
      int j = k / n;
      if (h[i][j] == '1') s[i] = false;
    }
    v[cc] = cnt;
  }
  vector<int> bel(n * d);
  for (int i = 0; i < scc.size(); i++)
    for (auto &j : scc[i]) bel[j] = i;
  vector<int> in(sz);
  for (int i = 0; i < n; i++)
    for (auto &j : g[i])
      for (int h = 0; h < d; h++)
        if (bel[n * h + i] != bel[n * ((h + 1) % d) + j])
          ++in[bel[n * ((h + 1) % d) + j]];
  queue<int> q;
  for (int i = 0; i < sz; i++)
    if (!in[i]) q.push(i);
  vector<int> ts;
  while (!q.empty()) {
    int c = q.front();
    q.pop();
    ts.push_back(c);
    for (auto &sc : scc[c]) {
      int i = sc % n, j = sc / n;
      for (auto &k : g[i])
        if (c != bel[n * ((j + 1) % d) + k]) {
          --in[bel[n * ((j + 1) % d) + k]];
          if (!in[bel[n * ((j + 1) % d) + k]])
            q.push(bel[n * ((j + 1) % d) + k]);
        }
    }
  }
  vector<int> dp(sz);
  for (int i = sz - 1; i >= 0; i--) {
    int c = ts[i];
    for (auto &sc : scc[c]) {
      int i = sc % n, j = sc / n;
      for (auto &k : g[i])
        if (c != bel[n * ((j + 1) % d) + k])
          dp[c] = max(dp[c], dp[bel[n * ((j + 1) % d) + k]]);
    }
    dp[c] += v[c];
  }
  cout << dp[bel[0]] << '\n';
  return 0;
}
