#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e6 + 5;
struct Edge {
  int to, nxt;
} edge[maxn];
int head[maxn];
int tot;
void addedge(int u, int v) {
  tot++;
  edge[tot].to = v;
  edge[tot].nxt = head[u];
  head[u] = tot;
}
int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc;
int w[maxn];
int S[maxn], top;
int n, m, d;
char s[100005][55];
int vis[100005];
void dfs(int u) {
  pre[u] = lowlink[u] = ++dfs_clock;
  S[++top] = u;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (!pre[v]) {
      dfs(v);
      lowlink[u] = min(lowlink[u], lowlink[v]);
    } else if (!sccno[v]) {
      lowlink[u] = min(lowlink[u], pre[v]);
    }
  }
  if (lowlink[u] == pre[u]) {
    scc++;
    for (;;) {
      int x = S[top];
      top--;
      sccno[x] = scc;
      int D = (x + n - 1) / n - 1, E = (x - 1) % n + 1;
      if (s[E][D] == '1' && vis[E] != scc) vis[E] = scc, w[scc]++;
      if (x == u) break;
    }
  }
}
void find_scc(int n) {
  for (int i = 1; i <= n; i++)
    if (!pre[i]) dfs(i);
}
int idx(int x, int y) { return y * n + x; }
int X[100005], Y[100005];
int dp[maxn];
void Solve(int u) {
  dp[u] = w[u];
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (dp[v] == -1) Solve(v);
    dp[u] = max(dp[u], dp[v] + w[u]);
  }
}
int main() {
  cin >> n >> m >> d;
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    X[i] = u;
    Y[i] = v;
    for (int j = 0; j < d; j++) {
      addedge(idx(u, j), idx(v, (j + 1) % d));
    }
  }
  for (int i = 1; i <= n; i++) scanf("%s", s[i]);
  find_scc(n * d);
  memset(head, 0, sizeof(head));
  tot = 0;
  for (int i = 1; i <= m; i++) {
    for (int j = 0; j < d; j++)
      if (sccno[idx(X[i], j)] != sccno[idx(Y[i], (j + 1) % d)]) {
        addedge(sccno[idx(X[i], j)], sccno[idx(Y[i], (j + 1) % d)]);
      }
  }
  memset(dp, -1, sizeof(dp));
  Solve(sccno[idx(1, 0)]);
  printf("%d\n", dp[sccno[idx(1, 0)]]);
  return 0;
}
