#include <bits/stdc++.h>
using namespace std;
using VI = vector<int>;
using VVI = vector<VI>;
using VB = vector<bool>;
using VS = vector<string>;
struct Pair {
  int cost, node;
  bool operator<(const Pair& p) const { return cost < p.cost; }
};
int N, M, D;
VVI G0, G;
VVI gc;
VS open;
VI scc;
VI m;
int nrc;
VI seen;
stack<int> st;
VI lv, low;
VB inStack;
int _lv;
void ReadData();
void Solve();
void BuildNewGraph();
inline void Tarjan(int node);
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);
  ReadData();
  Solve();
  return 0;
}
void ReadData() {
  cin >> N >> M >> D;
  G0 = VVI(N);
  int x, y;
  while (M--) {
    cin >> x >> y;
    --x;
    --y;
    G0[x].push_back(y);
  }
  open = VS(N);
  for (int i = 0; i < N; ++i) cin >> open[i];
}
void Solve() {
  BuildNewGraph();
  lv = low = VI(N * D);
  inStack = VB(N * D);
  scc = VI(N * D, -1);
  seen = VI(N);
  Tarjan(0);
  gc = VVI(nrc);
  for (int i = 0; i < N * D; ++i)
    for (const int& v : G[i])
      if (scc[i] != scc[v] && scc[i] != -1 && scc[v] != -1)
        gc[scc[i]].push_back(scc[v]);
  VI D(nrc, -1);
  int ans;
  D[scc[0]] = ans = m[scc[0]];
  priority_queue<Pair> Q;
  Q.push({D[scc[0]], scc[0]});
  while (!Q.empty()) {
    int x = Q.top().node;
    int cc = Q.top().cost;
    Q.pop();
    if (D[x] != cc) continue;
    for (const int& y : gc[x])
      if (D[x] + m[y] > D[y]) {
        D[y] = D[x] + m[y];
        Q.push({D[y], y});
        ans = max(ans, D[y]);
      }
  }
  cout << ans;
}
void BuildNewGraph() {
  G = VVI(N * D);
  for (int i = 0; i < N * D; ++i) {
    for (const int& v : G0[i % N])
      G[i].push_back((((i / N + 1) * N) + v) % (N * D));
  }
}
inline void Tarjan(int node) {
  lv[node] = low[node] = ++_lv;
  st.push(node);
  inStack[node] = true;
  for (const int& v : G[node]) {
    if (!lv[v]) {
      Tarjan(v);
      low[node] = min(low[node], low[v]);
    } else if (inStack[v])
      low[node] = min(low[node], low[v]);
  }
  if (lv[node] <= low[node]) {
    int x;
    m.push_back(0);
    do {
      x = st.top();
      st.pop();
      inStack[x] = false;
      scc[x] = nrc;
      if (seen[x % N] != nrc + 1 && open[x % N][x / N] == '1') {
        seen[x % N] = nrc + 1;
        ++m[nrc];
      }
    } while (x != node);
    ++nrc;
  }
}
