#include <bits/stdc++.h>
using namespace std;
int n, m, d;
vector<vector<int> > g;
vector<int> scc, num, low, in, dp, cost;
vector<set<int> > g_scc;
int cur_scc = 1, dfs_cnt = 1;
stack<int> st;
void dfs(int u) {
  num[u] = low[u] = dfs_cnt++;
  st.push(u);
  in[u] = 1;
  for (auto& v : g[u]) {
    if (num[v] == -1) {
      dfs(v);
      low[u] = min(low[u], low[v]);
    } else if (in[v]) {
      low[u] = min(low[u], num[v]);
    }
  }
  if (low[u] == num[u]) {
    while (st.top() != u) {
      int v = st.top();
      scc[v] = cur_scc;
      in[v] = 0;
      st.pop();
    }
    scc[u] = cur_scc;
    in[u] = 0;
    st.pop();
    cur_scc++;
  }
}
int solve(int u) {
  if (dp[u] != 0) {
    return dp[u];
  }
  for (auto& v : g_scc[u]) {
    dp[u] = max(dp[u], solve(v));
  }
  dp[u] += cost[u];
  return dp[u];
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m >> d;
  g.resize(n * d);
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    for (int t = 0; t < d; t++) {
      g[u * d + t].push_back(v * d + (t + 1) % d);
    }
  }
  num.assign(n * d, -1);
  low.resize(n * d);
  in.assign(n * d, 0);
  scc.resize(n * d);
  for (int i = 0; i < n * d; i++) {
    if (num[i] == -1) {
      dfs(i);
    }
  }
  num.clear();
  num.shrink_to_fit();
  low.clear();
  low.shrink_to_fit();
  in.clear();
  in.shrink_to_fit();
  g_scc.resize(cur_scc);
  cost.resize(cur_scc);
  dp.assign(cur_scc, 0);
  vector<int> last(cur_scc, -1);
  for (int i = 0; i < n; i++) {
    string open;
    cin >> open;
    for (int t = 0; t < d; t++) {
      int id = i * d + t;
      for (auto& v : g[id]) {
        if (scc[v] != scc[id]) {
          g_scc[scc[id]].insert(scc[v]);
        }
      }
      if (open[t] == '1') {
        if (last[scc[id]] != i) {
          last[scc[id]] = i;
          cost[scc[id]]++;
        }
      }
    }
  }
  g.clear();
  g.shrink_to_fit();
  cout << solve(scc[0]) << '\n';
  return 0;
}
