#include <bits/stdc++.h>
using std::abs;
using std::cin;
using std::cout;
using std::deque;
using std::function;
using std::make_pair;
using std::map;
using std::max;
using std::min;
using std::numeric_limits;
using std::pair;
using std::set;
using std::stack;
using std::string;
using std::stringstream;
using std::tuple;
using std::unordered_map;
using std::vector;
using ll = long long;
constexpr ll magic_mod = 1000000007;
ll m_pluss(ll a, ll b) { return (a + b) % magic_mod; }
ll m_mul(ll a, ll b) { return (a * b) % magic_mod; }
int n, m, dc;
vector<vector<int>> opposite_graph(vector<vector<int>> const& g) {
  int n = g.size();
  vector<vector<int>> h(n);
  for (int i = 0; (i) < (int)(n); ++(i))
    for (int j : g[i]) h[j].push_back(i);
  return h;
}
int t(int i, int j) {
  int shift = i / ::n;
  return (j + (shift + 1) * ::n) % (::n * ::dc);
}
int ti(int i, int j) {
  int shift = i / ::n;
  return (j + (shift + ::dc - 1) * ::n) % (::n * ::dc);
}
vector<vector<int>> decomposed_graph(int size, vector<int> const& component_of,
                                     vector<vector<int>> const& g) {
  int n = g.size() * ::dc;
  vector<vector<int>> h(size);
  for (int i = 0; (i) < (int)(n); ++(i))
    for (int j : g[i % ::n]) {
      if (component_of[i] != component_of[t(i, j)]) {
        h[component_of[i]].push_back(component_of[t(i, j)]);
      }
    }
  for (int k = 0; (k) < (int)(size); ++(k)) {
    sort(begin(h[k]), end(h[k]));
    h[k].erase(unique(begin(h[k]), end(h[k])), h[k].end());
  }
  return h;
}
pair<int, vector<int>> decompose_to_strongly_connected_components(
    vector<vector<int>> const& g, vector<vector<int>> const& g_rev) {
  int n = g.size() * ::dc;
  vector<int> acc(n);
  {
    auto it = acc.rbegin();
    vector<bool> used(n, false);
    stack<pair<int, int>> stk;
    for (int k = 0; (k) < (int)(n); ++(k))
      if (not used[k]) {
        stk.emplace(k, 0);
        used[k] = true;
        while (not stk.empty()) {
          int i = stk.top().first;
          int& e = stk.top().second;
          while (e < g[i % ::n].size()) {
            int j = t(i, g[i % ::n][e]);
            ++e;
            if (not used[j]) {
              stk.emplace(j, 0);
              used[j] = true;
              break;
            }
          }
          if (stk.top().first == i) {
            *(it++) = i;
            stk.pop();
          }
        }
      }
  }
  int size = 0;
  vector<int> component_of(n);
  {
    vector<bool> used(n, false);
    stack<int> stk;
    for (int k : acc)
      if (not used[k]) {
        stk.push(k);
        used[k] = true;
        while (not stk.empty()) {
          int i = stk.top();
          stk.pop();
          component_of[i] = size;
          for (int j : g_rev[i % ::n])
            if (not used[ti(i, j)]) {
              stk.push(ti(i, j));
              used[ti(i, j)] = true;
            }
        }
        ++size;
      }
  }
  return {size, move(component_of)};
}
int main() {
  std::ios_base::sync_with_stdio(0);
  std::cout.precision(17);
  cin >> n >> m >> dc;
  vector<vector<int>> g(n);
  vector<vector<int>> ginv(n);
  vector<bool> gus(n * dc, false);
  for (int i = 0; (i) < (int)(m); ++(i)) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    g[a].push_back(b);
    ginv[b].push_back(a);
  }
  string s;
  for (int i = 0; (i) < (int)(n); ++(i)) {
    cin >> s;
    for (int si = 0; (si) < (int)(dc); ++(si)) {
      if (s[si] == '1') {
        gus[si * n + i] = true;
      }
    }
  }
  auto sccs = decompose_to_strongly_connected_components(g, ginv);
  ginv.clear();
  ginv.shrink_to_fit();
  auto abstree = decomposed_graph(sccs.first, sccs.second, g);
  g.clear();
  g.shrink_to_fit();
  abstree = opposite_graph(abstree);
  int idx_ans = sccs.second[0];
  vector<pair<int, int>> xxx2;
  for (int i = 0; (i) < (int)(n * dc); ++(i)) {
    if (gus[i]) {
      xxx2.push_back({sccs.second[i], i % n});
    }
  }
  sort(begin(xxx2), end(xxx2));
  xxx2.erase(unique(begin(xxx2), end(xxx2)), xxx2.end());
  vector<pair<int, int>> scc_val(abstree.size(), {0, 0});
  for (auto dd : xxx2) {
    ++scc_val[dd.first].first;
  }
  sccs.second.clear();
  sccs.second.shrink_to_fit();
  vector<int> cc(abstree.size(), 0);
  for (int i = 0; (i) < (int)(abstree.size()); ++(i)) {
    for (auto j : abstree[i]) {
      cc[j]++;
    }
  }
  vector<int> curr;
  vector<int> next;
  for (int i = 0; (i) < (int)(abstree.size()); ++(i)) {
    if (cc[i] == 0) curr.push_back(i);
  }
  while (curr.size()) {
    next.clear();
    for (auto idx : curr) {
      for (auto j : abstree[idx]) {
        scc_val[j].second =
            max(scc_val[j].second, scc_val[idx].first + scc_val[idx].second);
        --cc[j];
        if (cc[j] == 0) {
          next.push_back(j);
        }
      }
    }
    curr.swap(next);
  }
  auto x = scc_val[idx_ans];
  cout << x.first + x.second << std::endl;
  return 0;
}
