#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T Read(T Type) {
  T x = 0, f = 1;
  char a = getchar();
  while (!('0' <= a && a <= '9')) {
    if (a == '-') f = -1;
    a = getchar();
  }
  while (('0' <= a && a <= '9')) {
    x = (x << 1) + (x << 3) + (a ^ '0');
    a = getchar();
  }
  return x * f;
}
const int MAXN = 5e6 + 10, MAXM = 5e6 + 10;
int cnt, head[MAXN];
struct EDGE {
  int u, v, next;
} edge[MAXM], sccedge[MAXM];
inline void add(int u, int v) {
  edge[++cnt].v = v;
  edge[cnt].u = u;
  edge[cnt].next = head[u];
  head[u] = cnt;
}
long long value[100010];
struct point {
  int low, dfn, scc;
} poi[MAXN];
struct SCC {
  int pow;
} scc[MAXN];
int T, scc_cnt, n, m, k;
bool instack[MAXN], flag[100010];
stack<int> st;
queue<int> used;
inline void Tarjan(int x) {
  st.push(x);
  instack[x] = 1;
  poi[x].dfn = poi[x].low = ++T;
  for (register int e = head[x]; e; e = edge[e].next) {
    int v = edge[e].v;
    if (!poi[v].dfn) {
      Tarjan(v);
      poi[x].low = min(poi[x].low, poi[v].low);
    } else if (instack[v])
      poi[x].low = min(poi[x].low, poi[v].dfn);
  }
  if (poi[x].low == poi[x].dfn) {
    scc[++scc_cnt].pow = 0;
    while (1) {
      int t = st.top();
      st.pop();
      int other = (t - 1) % n + 1;
      instack[t] = 0;
      poi[t].scc = scc_cnt;
      if (value[other] >> (t - 1) / n & 1 && !flag[other]) {
        flag[other] = 1;
        used.push(other);
        scc[scc_cnt].pow++;
      }
      if (t == x) break;
    }
    while (!used.empty()) {
      flag[used.front()] = 0;
      used.pop();
    }
  }
}
int tot, fire[MAXN];
inline void link(int u, int v) {
  sccedge[++tot].v = v;
  sccedge[tot].u = u;
  sccedge[tot].next = fire[u];
  fire[u] = tot;
}
inline void buildgraph() {
  for (register int i = 1; i <= n * k; i++) {
    if (!poi[i].dfn) continue;
    int u = poi[i].scc;
    for (register int j = head[i]; j; j = edge[j].next) {
      int v = poi[edge[j].v].scc;
      if (u ^ v) link(u, v);
    }
  }
}
int dp[MAXN];
inline void dfs(int x) {
  if (dp[x]) return;
  for (register int i = fire[x]; i; i = sccedge[i].next) {
    int v = sccedge[i].v;
    dfs(v);
    dp[x] = max(dp[x], dp[v]);
  }
  dp[x] += scc[x].pow;
}
int main() {
  n = Read(1), m = Read(1), k = Read(1);
  for (register int i = 1; i <= m; i++) {
    int u = Read(1), v = Read(1);
    for (register int dep = 0; dep < k; dep++)
      add(dep * n + u, (dep + 1) % k * n + v);
  }
  for (register int i = 1; i <= n; i++) {
    string a;
    cin >> a;
    for (register int j = 0; j < a.size(); j++)
      value[i] |= 1ll * (a[j] ^ '0') << j;
  }
  memset(poi, 0, sizeof(poi));
  Tarjan(1);
  buildgraph();
  dfs(poi[1].scc);
  printf("%d", dp[poi[1].scc]);
  return 0;
}
