#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
inline int rd() {
  int x = 0, w = 1;
  char ch = 0;
  while (ch < '0' || ch > '9') {
    if (ch == '-') w = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 3) + (x << 1) + (ch ^ 48);
    ch = getchar();
  }
  return x * w;
}
int to[N], nt[N], hd[N], dg[N], tot;
void add(int x, int y) {
  ++tot, to[tot] = y, nt[tot] = hd[x], hd[x] = tot, ++dg[y];
}
int n, m, d, e[N][2];
int dfn[N], low[N], ti, st[N], tp, sz[N], po[N];
bool v[N];
int findf(int x) { return po[x] == x ? x : po[x] = findf(po[x]); }
void tj(int x) {
  dfn[x] = low[x] = ++ti, st[++tp] = x, v[x] = 1;
  for (int i = hd[x]; i; i = nt[i]) {
    int y = to[i];
    if (!dfn[y])
      tj(y), low[x] = min(low[x], low[y]);
    else if (v[y])
      low[x] = min(low[x], low[y]);
  }
  if (dfn[x] == low[x]) {
    while (tp) {
      int y = st[tp--];
      po[y] = x, v[y] = 0;
      if (x == y) break;
      sz[x] += sz[y];
    }
  }
}
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int de[N], dd[N], a[N][51], f[N][51];
vector<int> scc[N];
void dfs(int x, int fk) {
  scc[fk].push_back(x);
  for (int i = hd[x]; i; i = nt[i]) {
    int y = to[i];
    if (findf(x) != findf(y)) continue;
    if (~de[y])
      dd[fk] = gcd(dd[fk], max(de[y] - de[x] + 1, de[x] - de[y] + 1));
    else
      de[y] = de[x] + 1, dfs(y, fk);
  }
}
char cc[N][52];
int main() {
  n = rd(), m = rd(), d = rd();
  for (int i = 1; i <= m; ++i) {
    e[i][0] = rd(), e[i][1] = rd();
    add(e[i][0], e[i][1]);
  }
  for (int i = 1; i <= n; ++i) sz[i] = 1, de[i] = -1, scanf("%s", cc[i]);
  for (int i = 1; i <= n; ++i)
    if (!dfn[i]) tj(i);
  for (int i = 1; i <= n; ++i)
    if (findf(i) == i) {
      de[i] = 0, dd[i] = d;
      dfs(i, i);
      int nn = scc[i].size();
      for (int j = 0; j < nn; ++j) de[scc[i][j]] %= dd[i];
      for (int j = 0; j < d; ++j) {
        for (int k = 0; k < nn; ++k) {
          int o = 0;
          for (int l = (j - de[i] + de[scc[i][k]]) % d; !o && l < d; l += dd[i])
            o |= cc[scc[i][k]][l] == '1';
          a[i][j] += o;
        }
      }
    }
  memset(hd, 0, sizeof(hd)), memset(dg, 0, sizeof(dg)), tot = 0;
  for (int i = 1; i <= m; ++i) {
    int x = findf(e[i][0]), y = findf(e[i][1]);
    if (x != y)
      add(x, y);
    else
      ++tot;
  }
  queue<int> q;
  memset(f, -0x7f, sizeof(f));
  if (dd[findf(1)] != d)
    for (int i = 0; i < d; i += dd[findf(1)]) f[findf(1)][i] = a[findf(1)][i];
  else
    f[findf(1)][de[findf(1)]] = a[findf(1)][de[findf(1)]];
  for (int i = 1; i <= n; ++i)
    if (findf(i) == i && !dg[i]) q.push(i);
  int ans = 0;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = 0; i < d; ++i) ans = max(ans, f[x][i]);
    for (int i = hd[x]; i; i = nt[i]) {
      int y = to[i];
      --dg[y];
      if (!dg[y]) q.push(y);
      int xx = e[i][0], yy = e[i][1];
      for (int j = 0; j < d; ++j) {
        int k = (j - de[xx] - de[x] + dd[x] + dd[x]) % dd[x],
            l = (j + 1 - de[yy] - de[y] + dd[y] + dd[y]) % dd[y];
        f[y][l] = max(f[y][l], f[x][k] + a[y][l]);
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
