#include <bits/stdc++.h>
using namespace std;
const int MAXN = int(1e5 + 5);
const int MAXD = 50;
int n, m, d;
int ncnt, tcnt;
int dfn[MAXN * MAXD], low[MAXN * MAXD], scc[MAXN * MAXD];
stack<int> S;
int tag[MAXN * MAXD];
int dp[MAXN * MAXD], val[MAXN * MAXD];
bool vis[MAXN * MAXD];
int cnt;
struct edge {
  int v, nxt;
} e1[MAXN * MAXD], e2[MAXN * MAXD];
int hd1[MAXN * MAXD], hd2[MAXN * MAXD];
void Addedge1(int x, int y) { e1[++cnt] = (edge){y, hd1[x]}, hd1[x] = cnt; }
void Addedge2(int x, int y) { e2[++cnt] = (edge){y, hd2[x]}, hd2[x] = cnt; }
void Dfs(int u) {
  low[u] = dfn[u] = ++ncnt;
  S.push(u);
  for (int i = hd1[u]; i; i = e1[i].nxt) {
    int v = e1[i].v;
    if (!dfn[v]) {
      Dfs(v);
      low[u] = min(low[u], low[v]);
    } else if (!scc[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    tcnt++;
    int v;
    do {
      v = S.top();
      S.pop();
      scc[v] = tcnt;
    } while (v != u);
  }
}
int Dfs2(int u) {
  if (vis[u]) return dp[u];
  vis[u] = true;
  for (int i = hd2[u]; i; i = e2[i].nxt) {
    int v = e2[i].v;
    dp[u] = max(dp[u], Dfs2(v));
  }
  dp[u] += val[u];
  return dp[u];
}
int main() {
  scanf("%d%d%d", &n, &m, &d);
  int u, v;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &u, &v);
    for (int j = 0; j <= d - 1; j++)
      Addedge1(u + (j % d) * n, v + ((j + 1) % d) * n);
  }
  for (int i = 1; i <= n * d; i++)
    if (!dfn[i]) Dfs(i);
  cnt = 0;
  for (int u = 1; u <= n * d; u++)
    for (int i = hd1[u]; i; i = e1[i].nxt) {
      int v = e1[i].v;
      if (scc[u] != scc[v]) Addedge2(scc[u], scc[v]);
    }
  char op[MAXD];
  for (int i = 1; i <= n; i++) {
    scanf("%s", op);
    for (int j = 0; j < d; j++)
      if (op[j] == '1' && tag[scc[i + j * n]] != i) {
        tag[scc[i + j * n]] = i;
        val[scc[i + j * n]]++;
      }
  }
  printf("%d", Dfs2(scc[1]));
}
