#include <bits/stdc++.h>
using namespace std;
int n, m, d;
vector<int> e[100000 + 5], lst[100000 + 5];
int dfn[100000 + 5], low[100000 + 5], cnt, tot, sta[100000 + 5], ptr,
    scc[100000 + 5], cycle[100000 + 5];
char open[100000 + 5][55];
void tarjan(int now) {
  dfn[now] = low[now] = ++cnt;
  sta[++ptr] = now;
  for (auto v : e[now]) {
    if (!dfn[v]) {
      tarjan(v);
      low[now] = min(low[now], low[v]);
    } else if (!scc[v])
      low[now] = min(low[now], dfn[v]);
  }
  if (low[now] == dfn[now]) {
    tot++;
    while (sta[ptr] != now) scc[sta[ptr--]] = tot;
    scc[sta[ptr--]] = tot;
  }
  return;
}
int gcd(int x, int y) { return x ? gcd(y % x, x) : y; }
int _gcd[55];
bool can[100000 + 5][55];
int off[100000 + 5];
pair<int, int> q[100000 * 50 + 5];
void bfs(int s, int id) {
  int rear = 0;
  q[rear].first = s;
  q[rear].second = 0;
  can[s][0] = 1;
  for (int front = 0; front <= rear; front++) {
    int now = q[front].first;
    int day = q[front].second;
    int nd = (day + 1) % d;
    for (auto v : e[now])
      if (scc[v] == id) {
        if (can[v][nd] == 0) {
          can[v][nd] = 1;
          rear++;
          q[rear].first = v;
          q[rear].second = nd;
        }
      }
  }
  cycle[id] = d;
  for (int i = 1; i <= d - 1; i++)
    if (can[s][i]) {
      cycle[id] = i;
      break;
    }
  assert(d % cycle[id] == 0);
}
int dp[100000 + 5][55], dpscc[100000 + 5][55];
void upd(int &x, int y) {
  if (y > x) x = y;
}
int main() {
  scanf("%d%d%d", &n, &m, &d);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    e[x].push_back(y);
  }
  for (int i = 1; i <= n; i++) scanf("%s", open[i]);
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= n; i++) lst[scc[i]].push_back(i);
  for (int i = 1; i <= tot; i++) bfs(lst[i][0], i);
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= d - 1; j++)
      if (can[i][j]) {
        off[i] = j;
        break;
      }
  }
  memset(dp, -1, sizeof dp);
  memset(dpscc, -1, sizeof dpscc);
  int ans = 0;
  dpscc[scc[1]][0] = 0;
  for (int id = tot; id >= 1; id--) {
    int c = cycle[id];
    int cnt[55] = {};
    for (auto now : lst[id]) {
      bool tmp[55] = {};
      for (int i = 0; i <= d - 1; i++)
        if (open[now][i] == '1') tmp[(i - off[now] + c) % c] = 1;
      for (int i = 0; i <= d - 1; i++) cnt[i] += tmp[i];
    }
    for (auto now : lst[id]) {
      for (int i = 0; i <= d - 1; i++)
        if (dpscc[id][(i - off[now] + c) % c] >= 0)
          dp[now][i] =
              dpscc[id][(i - off[now] + c) % c] + cnt[(i - off[now] + c) % c];
      for (int i = 0; i <= d - 1; i++) ans = max(ans, dp[now][i]);
    }
    for (auto now : lst[id])
      for (auto v : e[now])
        if (scc[v] != id) {
          int nid = scc[v];
          for (int i = 0; i <= d - 1; i++)
            upd(dpscc[nid][(i + 1 - off[v] + cycle[nid]) % cycle[nid]],
                dp[now][i]);
        }
  }
  printf("%d\n", ans);
  return 0;
}
