#include <bits/stdc++.h>
using std::cerr;
using std::cin;
using std::max;
using std::min;
int n, m, K, a, b, ecnt, last[100005], idx, dfn[100005], low[100005],
    sta[100005], top, ins[100005], tot, bel[100005], val[100005], G[100005],
    deep[100005], f[100005][55], cnt[100005][55], deg[100005], ans;
char s[100005][55];
std::vector<int> S[100005], E[100005];
std::queue<int> q;
struct road {
  int to, nex;
} e[100005];
void adde(int u, int v) { e[++ecnt] = (road){v, last[u]}, last[u] = ecnt; }
int gcd(int x, int y) { return y ? gcd(y, x % y) : x; }
void tarjan(int x) {
  dfn[x] = low[x] = ++idx, sta[++top] = x, ins[x] = 1;
  for (int k = last[x]; k; k = e[k].nex)
    if (!dfn[e[k].to])
      tarjan(e[k].to), low[x] = min(low[x], low[e[k].to]);
    else if (ins[e[k].to])
      low[x] = min(low[x], dfn[e[k].to]);
  if (low[x] == dfn[x]) {
    tot++;
    int tmp;
    do tmp = sta[top--], ins[tmp] = 0, bel[tmp] = tot;
    while (tmp ^ x);
  }
}
void dfs(int x, int fath = 0) {
  deep[x] = deep[fath] + 1;
  for (int k = last[x]; k; k = e[k].nex)
    if (bel[x] == bel[e[k].to]) {
      if (!deep[e[k].to])
        dfs(e[k].to, x), G[x] = gcd(G[x], G[e[k].to]);
      else
        G[x] = gcd(G[x], abs(deep[x] - deep[e[k].to] + 1));
    }
  val[bel[x]] = gcd(val[bel[x]], G[x]);
}
int main() {
  scanf("%d%d%d", &n, &m, &K);
  for (int i = 1; i <= m; i++) scanf("%d%d", &a, &b), adde(a, b);
  for (int i = 1; i <= n; i++) scanf("%s", s[i]);
  tarjan(1);
  for (int i = 1; i <= n; i++)
    if (!deep[i]) dfs(i);
  for (int i = 0; i <= tot; i++) val[i] = gcd(val[i], K);
  for (int i = 1; i <= n; i++) S[bel[i]].push_back(i);
  for (int i = 1; i <= n; i++)
    for (int k = last[i]; k; k = e[k].nex)
      if (bel[i] && bel[e[k].to] && bel[i] ^ bel[e[k].to])
        E[bel[i]].push_back(bel[e[k].to]), deg[bel[e[k].to]]++;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < K; j++)
      if (s[i][j] - 48) s[i][j % val[bel[i]]] = '1';
    for (int j = 0; j < val[bel[i]]; j++)
      cnt[bel[i]][j] += s[i][(j + deep[i] - 1) % val[bel[i]]] - 48;
  }
  for (int i = 1; i <= tot; i++)
    for (int j = 0; j < K; j++) f[i][j] = -1e9;
  f[bel[1]][0] = 0, q.push(bel[1]);
  for (int top, t; !q.empty();) {
    top = q.front(), q.pop();
    for (int i = 0; i < K; i++)
      f[top][i % val[top]] = max(f[top][i % val[top]], f[top][i]);
    for (int i = 0; i < val[top]; i++) {
      f[top][i] += cnt[top][i], ans = max(ans, f[top][i]);
      for (int j = i + val[top]; j < K; j += val[top]) f[top][j] = f[top][i];
    }
    for (int x : S[top]) {
      for (int k = last[x]; k; k = e[k].nex)
        if (bel[e[k].to] && bel[e[k].to] ^ top) {
          for (int i = 0; i < K; i++) {
            t = (i + deep[x] - 1) % K,
            t = ((t - deep[e[k].to] + 1) % K + K) % K, t = (t + 1) % K;
            f[bel[e[k].to]][t] = max(f[bel[e[k].to]][t], f[top][i]);
          }
        }
    }
    for (int to : E[top])
      if (!--deg[to]) q.push(to);
  }
  printf("%d\n", ans);
  return 0;
}
