#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,abm,mmx,avx")
template <typename T1, typename T2>
inline bool chkmin(T1& x, const T2& y) {
  if (x > y) {
    x = y;
    return 1;
  }
  return 0;
}
template <typename T1, typename T2>
inline bool chkmax(T1& x, const T2& y) {
  if (x < y) {
    x = y;
    return 1;
  }
  return 0;
}
using namespace std;
const int maxn = 1e5 + 20;
ostream& operator<<(ostream& out, vector<int>& v) {
  for (auto& x : v) out << x << ' ';
  return out;
}
ostream& operator<<(ostream& out, pair<int, int>& v) {
  out << v.first << ", " << v.second;
  return out;
}
istream& operator>>(istream& in, pair<int, int>& a) {
  in >> a.first >> a.second;
  return in;
}
const long long inf = (long long)2e9;
const long double pi = asin(1) * 2;
const long double eps = 1e-8;
const long long mod = (long long)1e9 + 7;
const long long ns = 97;
const int maxd = 50 + 5;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
vector<int> gr[maxn], g[maxn];
int c[maxn][maxd], cnt[maxn * maxd], dp[maxn * maxd], n, d;
bool used[maxn][maxd], kek[maxn][maxd], u[maxn];
vector<pair<int, int> > order, sh[maxn * maxd];
void dfs1(int v, int t) {
  used[v][t] = 1;
  for (auto& u : g[v]) {
    if (!used[u][(t + 1) % d]) dfs1(u, (t + 1) % d);
  }
  order.push_back({v, t});
}
void dfs2(int v, int t, int cmp) {
  used[v][t] = 1;
  c[v][t] = cmp;
  sh[cmp].push_back({v, t});
  for (auto& u : gr[v]) {
    if (!used[u][(t - 1 + d) % d]) dfs2(u, (t - 1 + d) % d, cmp);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  for (auto& v : c)
    for (auto& x : v) x = -1;
  int m;
  cin >> n >> m >> d;
  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    g[a].push_back(b);
    gr[b].push_back(a);
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < d; ++j) {
      char x;
      cin >> x;
      kek[i][j] = x == '1';
    }
  }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < d; ++j)
      if (!used[i][j]) dfs1(i, j);
  reverse(order.begin(), order.end());
  for (auto& v : used)
    for (auto& x : v) x = 0;
  int cmp = 0;
  for (auto& x : order) {
    if (!used[x.first][x.second]) {
      dfs2(x.first, x.second, cmp);
      ++cmp;
    }
  }
  for (int i = 0; i < cmp; ++i) {
    for (auto& x : sh[i]) {
      if (!u[x.first] && kek[x.first][x.second]) {
        ++cnt[i];
        u[x.first] = 1;
      }
    }
    for (auto& x : sh[i]) u[x.first] = 0;
  }
  for (int i = cmp - 1; i >= 0; --i) {
    dp[i] = cnt[i];
    for (auto& v : sh[i]) {
      for (auto& u : g[v.first]) {
        if (c[u][(v.second + 1) % d] == -1) continue;
        if (i != c[u][(v.second + 1) % d]) {
          chkmax(dp[i], dp[c[u][(v.second + 1) % d]] + cnt[i]);
        }
      }
    }
  }
  cout << dp[c[0][0]] << '\n';
}
