#include <bits/stdc++.h>
using namespace std;
const int sz = 1e5 + 1;
int u, v;
int n, m, d;
int cnt, tot;
int w[sz * 50];
int f[sz * 50], r[sz * 50];
int bl[sz * 50], W[sz * 50];
int head[sz * 50], Head[sz * 50];
int dfn[sz * 50], low[sz * 50];
char s[sz][51];
bool in[sz * 50];
bool b[sz];
stack<int> S;
queue<int> q;
struct wxp {
  int v, nxt;
} edge[sz * 50], Edge[sz * 50];
void add(int u, int v) {
  edge[++cnt] = (wxp){v, head[u]};
  head[u] = cnt;
}
void Add(int u, int v) {
  Edge[++cnt] = (wxp){v, Head[u]};
  Head[u] = cnt;
}
inline void tarjan(int x) {
  in[x] = 1;
  S.push(x);
  dfn[x] = low[x] = ++cnt;
  for (int i = head[x]; i; i = edge[i].nxt)
    if (!dfn[edge[i].v]) {
      tarjan(edge[i].v);
      low[x] = min(low[x], low[edge[i].v]);
    } else if (in[edge[i].v])
      low[x] = min(low[x], dfn[edge[i].v]);
  if (dfn[x] == low[x]) {
    tot++;
    while (!S.empty() && S.top() != x) {
      int t = S.top();
      S.pop();
      in[t] = 0;
      bl[t] = tot;
      if (w[t] && !b[t % n]) W[tot]++, b[t % n] = 1, q.push(t % n);
    }
    int t = S.top();
    S.pop();
    in[t] = 0;
    bl[t] = tot;
    if (w[t] && !b[t % n]) W[tot]++, b[t % n] = 1, q.push(t % n);
    while (!q.empty()) b[q.front()] = 0, q.pop();
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &d);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &u, &v);
    for (int j = 0; j <= d - 1; j++) add(u + j * n, v + (j + 1) % d * n);
  }
  for (int i = 1; i <= n; i++) scanf("%s", s[i]);
  for (int i = 1; i <= n; i++)
    for (int j = 0; j <= d - 1; j++) w[i + j * n] = s[i][j] - '0';
  cnt = 0;
  for (int i = 1; i <= n * d; i++)
    if (!dfn[i]) tarjan(i);
  cnt = 0;
  for (int j = 1; j <= n * d; j++)
    for (int i = head[j]; i; i = edge[i].nxt)
      if (bl[j] != bl[edge[i].v]) {
        Add(bl[edge[i].v], bl[j]);
        r[bl[j]]++;
      }
  for (int i = 1; i <= tot; i++) {
    f[i] = W[i];
    if (!r[i]) q.push(i);
  }
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (int i = Head[u]; i; i = Edge[i].nxt) {
      f[Edge[i].v] = max(f[Edge[i].v], f[u] + W[Edge[i].v]);
      r[Edge[i].v]--;
      if (!r[Edge[i].v]) q.push(Edge[i].v);
    }
  }
  printf("%d", f[bl[1]]);
}
