#include <bits/stdc++.h>
using namespace std;
int n, m, d, a, b, kcmp = -1, kcmp2 = -1;
vector<vector<int> > G, U, M;
vector<int> met, comp, ord, kol, dp;
vector<string> D;
queue<pair<int, int> > och;
set<int> tek;
stack<pair<int, int> > st1;
queue<int> st2;
void dfs1(int a) {
  met[a] = 1;
  for (auto to : G[a])
    if (!met[to]) dfs1(to);
  ord.push_back(a);
}
void dfs2(int a) {
  comp[a] = kcmp;
  for (auto to : U[a])
    if (comp[to] == -1) dfs2(to);
}
int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m >> d;
  G.resize(n);
  U.resize(n);
  met.resize(n, 0);
  comp.resize(n, -1);
  D.resize(n);
  M.resize(n, vector<int>(d, -1));
  for (int i = 0; i < m; i++) {
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
    U[b].push_back(a);
  }
  for (int i = 0; i < n; i++) cin >> D[i];
  vector<int> todfs(n, -1);
  int inf = 1e9;
  for (int i = 0; i < n; i++)
    if (todfs[i] == -1) {
      todfs[i]++;
      st1.push({i, todfs[i]});
      while ((int)st1.size()) {
        pair<int, int> q = st1.top();
        st1.pop();
        if (q.second == todfs[q.first] && todfs[q.first] < inf) {
          st1.push({q.first, inf});
          todfs[q.first] = inf;
          for (int j = (int)G[q.first].size() - 1; j >= 0; j--)
            if (todfs[G[q.first][j]] < inf) {
              todfs[G[q.first][j]]++;
              st1.push({G[q.first][j], todfs[G[q.first][j]]});
            }
        } else if (q.second == inf) {
          ord.push_back(q.first);
        }
      }
    }
  for (int i = (int)ord.size() - 1; i >= 0; i--) {
    int w = ord[i];
    if (comp[w] == -1) {
      kcmp++;
      comp[w] = kcmp;
      st2.push(w);
      while ((int)st2.size()) {
        int z = st2.front();
        st2.pop();
        for (auto to : U[z])
          if (comp[to] == -1) {
            comp[to] = kcmp;
            st2.push(to);
          }
      }
    }
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < d; j++)
      if (M[i][j] == -1) {
        kcmp2++;
        M[i][j] = kcmp2;
        och.push({i, j});
        while ((int)och.size() > 0) {
          int zx = och.front().first;
          int zy = och.front().second;
          for (auto to : G[zx])
            if (comp[to] == comp[zx] && M[to][(zy + 1) % d] == -1) {
              M[to][(zy + 1) % d] = kcmp2;
              och.push({to, (zy + 1) % d});
            }
          och.pop();
        }
      }
  kcmp2++;
  kol.resize(kcmp2, 0);
  for (int i = 0; i < n; i++) {
    tek.clear();
    for (int j = 0; j < d; j++)
      if (D[i][j] == '1') tek.insert(M[i][j]);
    for (auto q : tek) kol[q]++;
  }
  dp.resize(kcmp2, 0);
  for (int i = 0; i < (int)kol.size(); i++) dp[i] = kol[i];
  for (auto a : ord)
    for (auto to : G[a])
      if (comp[a] != comp[to])
        for (int i = 0; i < d; i++) {
          int a2 = M[a][i];
          int to2 = M[to][(i + 1) % d];
          dp[a2] = max(dp[a2], kol[a2] + dp[to2]);
        }
  cout << dp[0];
}
