#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const int INF = 1000 * 1000 * 1000 + 7;
const long long LINF = (long long)INF * INF;
const int MAX = 100 * 1000 + 7;
int n, m, d;
long long open[MAX];
vector<int> g[MAX], gt[MAX];
bool used1[MAX];
bool used2[MAX];
vector<int> order;
vector<int> comps[MAX];
int scc[MAX];
long long can[50][MAX];
int len[MAX];
int a[MAX][50];
int dp[MAX][50];
pair<int, int> st[50 * MAX];
int gcd[50 * MAX];
char s[50];
void dfs1(int v) {
  used1[v] = true;
  for (int to : g[v]) {
    if (!used1[to]) {
      dfs1(to);
    }
  }
  order.push_back(v);
}
void dfs2(int v, int c) {
  used2[v] = true;
  scc[v] = c;
  comps[c].push_back(v);
  for (int to : gt[v]) {
    if (used1[to] && !used2[to]) {
      dfs2(to, c);
    }
  }
}
void dfs3(int leader, int start) {
  st[0] = make_pair(leader, start);
  int ptr = 1;
  can[start][leader] |= 1LL << start;
  while (ptr) {
    ptr--;
    int v = st[ptr].first;
    int day = st[ptr].second;
    for (int to : g[v]) {
      int dayTo = day + 1 == d ? 0 : day + 1;
      if (scc[to] == scc[v] && !((can[start][to] >> dayTo) & 1)) {
        can[start][to] |= 1LL << dayTo;
        st[ptr++] = make_pair(to, dayTo);
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &d);
  for (int i = (0); i < (m); ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--;
    v--;
    g[u].push_back(v);
    gt[v].push_back(u);
  }
  for (int i = (0); i < (n); ++i) {
    scanf("%s", s);
    for (int j = (0); j < (d); ++j) {
      if (s[j] == '1') {
        open[i] |= 1LL << j;
      }
    }
  }
  dfs1(0);
  int cntComps = 0;
  for (int i = ((int)((order).size())) - 1; i >= (0); --i) {
    if (used1[order[i]] && !used2[order[i]]) {
      dfs2(order[i], cntComps++);
    }
  }
  for (int i = (0); i < (cntComps); ++i) {
    gcd[i] = d;
    for (int j = (0); j < (gcd[i]); ++j) {
      dfs3(comps[i][0], j);
      for (int v : comps[i]) {
        a[i][j] += (bool)(can[j][v] & open[v]);
      }
      if (j == 0) {
        for (int v : comps[i]) {
          assert(can[0][v] != 0);
          while (!((can[0][v] >> len[v]) & 1)) {
            len[v]++;
          }
        }
        for (int k = (1); k < (d); ++k) {
          if ((can[0][comps[i][0]] >> k) & 1) {
            gcd[i] = k;
            break;
          }
        }
      }
    }
  }
  for (int i = (cntComps)-1; i >= (0); --i) {
    for (int j = (0); j < (d); ++j) {
      dp[i][j] = a[i][j];
    }
    for (int v : comps[i]) {
      for (int k = (0); k < (d); ++k) {
        int j = (k - len[v] + d) % gcd[i];
        for (int to : g[v]) {
          if (scc[to] != i) {
            dp[i][j] = max(
                dp[i][j],
                a[i][j] + dp[scc[to]][(k + 1 - len[to] + d) % gcd[scc[to]]]);
          }
        }
      }
    }
  }
  printf("%d", dp[0][(d - len[0]) % gcd[0]]);
  return 0;
}
