#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 50, M = 55;
int B, bl[N];
vector<int> bcc[N];
inline void update(int &a, int b) { a = max(a, b); }
int n, m, d;
int dp[N * M];
char op[N][M];
vector<int> G[N], G2[N], G3[N];
void add(int u, int v, vector<int> G[]) { G[u].push_back(v); }
bool vis[N][M];
bool tv[N];
int val[N * M];
int c[N][M], tot;
vector<int> path;
void dfs(int u, int j, vector<int> G[], int col) {
  vis[u][j] = 1;
  c[u][j] = col;
  if (op[u][j] == '1' && !tv[u]) {
    tv[u] = 1;
    ++val[col];
    path.push_back(u);
  }
  for (int v : G[u]) {
    if (!vis[v][(j + 1) % d]) dfs(v, (j + 1) % d, G, col);
  }
}
void doit(int bid) {
  for (int bx : bcc[bid])
    for (int j = 0; j < d; ++j)
      if (!vis[bx][j]) {
        path.clear();
        dfs(bx, j, G2, ++tot);
        for (int x : path) tv[x] = 0;
      }
}
int topo(vector<int> G[]) {
  for (int i = 0; i < B; ++i) {
    for (int bx : bcc[i])
      for (int j = 0; j < d; ++j) {
        int uc = c[bx][j], u = bx;
        for (int v : G[u]) {
          int vc = c[v][(j + d - 1) % d];
          update(dp[vc], dp[uc] + val[uc]);
        }
      }
  }
  int cc = c[0][0];
  return dp[cc] + val[cc];
}
pair<int, int> e[N];
namespace tarjan {
int low[N], dfn[N], clk;
void init(int n) {
  B = clk = 0;
  memset(dfn, 0, sizeof(int) * (n + 1));
  for (int i = 0; i < n; ++i) bcc[i].clear();
}
void tarjan(int u) {
  static int st[N], p;
  static bool in[N];
  dfn[u] = low[u] = ++clk;
  st[p++] = u;
  in[u] = true;
  for (int &v : G[u]) {
    if (!dfn[v]) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (in[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    while (1) {
      int x = st[--p];
      in[x] = false;
      bl[x] = B;
      bcc[B].push_back(x);
      if (x == u) break;
    }
    ++B;
  }
}
void go(int n) {
  init(n);
  for (int i = 0; i < n; ++i) {
    if (!dfn[i]) tarjan(i);
  }
}
}  // namespace tarjan
int main(int argc, char const *argv[]) {
  scanf("%d%d%d", &n, &m, &d);
  for (int i = 0; i < m; ++i) {
    scanf("%d%d", &e[i].first, &e[i].second);
    --e[i].first;
    --e[i].second;
    add(e[i].first, e[i].second, G);
  }
  for (int i = 0; i < n; ++i) scanf("%s", op[i]);
  tarjan::go(n);
  for (int i = 0; i < m; ++i) {
    int u = e[i].first, v = e[i].second;
    if (bl[u] == bl[v])
      add(u, v, G2);
    else
      add(v, u, G3);
  }
  for (int i = 0; i < B; ++i) doit(i);
  int ans = topo(G3);
  cout << ans << endl;
  return 0;
}
