#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma warning(disable : 4996)
using namespace std;
namespace Bigcat {
template <typename T>
inline void max_s(T& a, const T& b) {
  a = max(a, b);
}
template <typename T>
inline void min_s(T& a, const T& b) {
  a = min(a, b);
}
template <typename T>
void sort_v(T& x) {
  sort(x.begin(), x.end());
}
template <typename T>
void erase_dup(T& x) {
  x.erase(unique(x.begin(), x.end()), x.end());
}
template <typename T, typename V>
int pos_l(const T& x, const V& v) {
  return lower_bound(x.begin(), x.end(), v) - x.begin();
}
template <typename T, typename V>
int pos_u(const T& x, const V& v) {
  return upper_bound(x.begin(), x.end(), v) - x.begin();
}
inline unsigned rand_g() {
  static mt19937 mt_rand((int)time(0));
  return mt_rand();
}
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<LL>;
using PII = pair<int, int>;
using VPII = vector<PII>;
}  // namespace Bigcat
using namespace Bigcat;
const LL base = LL(1e9 + 7);
const LL INFL = 1LL << 62;
const int INF = 1 << 30;
const int MAX = int(1e5 + 100);
const int MAX2 = MAX * 50;
int n, m, d;
VI gr[MAX];
VI stk;
int dfsn[MAX2];
int acc;
bool instk[MAX2];
int low[MAX2];
int color[MAX2];
int totColor;
void tarjan(int v) {
  low[v] = dfsn[v] = ++acc;
  stk.push_back(v);
  instk[v] = true;
  int nxd = (v % d + 1) % d;
  for (auto x : gr[v / d]) {
    int nx = x * d + nxd;
    if (dfsn[nx] == 0) {
      tarjan(nx);
      min_s(low[v], low[nx]);
    } else {
      if (instk[nx]) min_s(low[v], low[nx]);
    }
  }
  if (low[v] < dfsn[v]) return;
  while (true) {
    int t = stk.back();
    color[t] = totColor;
    stk.pop_back();
    instk[t] = false;
    if (t == v) break;
  }
  ++totColor;
}
string open[MAX];
vector<VI> ngr;
VI zs;
VI ss;
void solve1() {
  if (-1 > ngr.size()) {
    int x = 1;
  }
  LL result = 0;
  cin >> n >> m >> d;
  for (int i = 0; i < (int)(m); i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    gr[u].push_back(v);
  }
  memset(color, -1, sizeof(color));
  tarjan(0);
  for (int i = 0; i < (int)(n); i++) {
    cin >> open[i];
  }
  ngr.resize(totColor + 1);
  zs.resize(totColor + 1);
  ss.assign(totColor + 1, 0);
  for (int i = 0; i < (int)(n); i++) {
    set<int> t;
    for (int j = 0; j < (int)(d); j++) {
      if (open[i][j] == '1') t.insert(color[i * d + j]);
    }
    for (auto x : t) {
      if (x >= 0) zs[x]++;
    }
  }
  for (int i = 0; i < (int)(n * d); i++) {
    int nxd = (i % d + 1) % d;
    int c = color[i];
    if (c < 0) continue;
    for (auto x : gr[i / d]) {
      int nx = x * d + nxd;
      int c1 = color[nx];
      if (c1 < 0) continue;
      if (c == c1) continue;
      ngr[c].push_back(c1);
    }
  }
  for (int i = 0; i < (int)(totColor); i++) {
    for (auto x : ngr[i]) {
      max_s(ss[i], ss[x]);
    }
    ss[i] += zs[i];
  }
  auto x = max_element(ss.begin(), ss.end());
  result = *x;
  cout << result << endl;
}
void solve() {
  int t = 1;
  for (int i = 0; i < t; ++i) {
    solve1();
  }
  int x = 1;
}
void io_init() {
  const int inId = 0;
  const int outId = 0;
  if (inId > 0) {
    cerr << "redirect stdin to input " << inId << endl;
    string s = "input";
    s += to_string(inId);
    s += ".txt";
    auto r = freopen(s.c_str(), "r", stdin);
    if (r == nullptr) {
      cerr << "invalid input file " << s << endl;
      ;
      r = freopen("CON", "r", stdin);
    }
  }
  if (outId > 0) {
    cerr << "redirect stdout to stdout " << outId << endl;
    string s = "stdout";
    s += to_string(outId);
    s += ".txt";
    auto r = freopen(s.c_str(), "w", stdout);
    if (r == nullptr) {
      cerr << "invalid output file " << s << endl;
      ;
      r = freopen("CON", "w", stdout);
    }
  }
}
int main(int argc, char* argv[]) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(11);
  solve();
}

### Prompt

Create a solution in cpp for the following problem:

In the country N, there are n cities connected by m one-way roads. Although this country seems unremarkable, there are two interesting facts about it. At first, a week lasts d days here. At second, there is exactly one museum in each city of the country N.

Travel agency "Open museums" is developing a new program for tourists interested in museums. Agency's employees know which days each of the museums is open. The tour should start in the capital — the city number 1, and the first day of the tour must be on the first day of a week. Each day a tourist will be in some city, watching the exposition in its museum (in case museum is open today), and by the end of the day, the tour either ends or the tourist goes into another city connected by a road with the current one. The road system of N is designed in such a way that traveling by a road always takes one night and also all the roads are one-way. It's allowed to visit a city multiple times during the trip.

You should develop such route for the trip that the number of distinct museums, possible to visit during it, is maximum.

Input

The first line contains three integers n, m and d (1 ≤ n ≤ 100 000, 0 ≤ m ≤ 100 000, 1 ≤ d ≤ 50), the number of cities, the number of roads and the number of days in a week.

Each of next m lines contains two integers u_i and v_i (1 ≤ u_i, v_i ≤ n, u_i ≠ v_i), denoting a one-way road from the city u_i to the city v_i.

The next n lines contain the museums' schedule. The schedule of the museum located in the i-th city is described in the i-th of these lines. Each line consists of exactly d characters "0" or "1", the j-th character of the string equals to "1" if the museum is open at the j-th day of a week, and "0", otherwise.

It's guaranteed that for each pair of cities (u, v) there exists no more than one road leading from u to v.

Output

Print a single integer — the maximum number of distinct museums, that it's possible to visit, starting a trip in the first city on the first day of the week.

Examples

Input


4 5 3
3 1
1 2
2 4
4 1
2 3
011
110
111
001


Output


3


Input


3 3 7
1 2
1 3
2 3
1111111
0000000
0111111


Output


2

Note

Explanation of the first example <image>

The maximum number of distinct museums to visit is 3. It's possible to visit 3 museums, for example, in the way described below.

  * Day 1. Now it's the 1st day of a week, and the tourist is in the city 1. The museum there is closed. At night the tourist goes to the city number 2. 
  * Day 2. Now it's the 2nd day of a week, and the tourist is in the city 2. The museum there is open, and the tourist visits it. At night the tourist goes to the city number 4. 
  * Day 3. Now it's the 3rd day of a week, and the tourist is in the city 4. The museum there is open, and the tourist visits it. At night the tourist goes to the city number 1. 
  * Day 4. Now it's the 1st day of a week, and the tourist is in the city 1. The museum there is closed. At night the tourist goes to the city number 2. 
  * Day 5. Now it's the 2nd of a week number 2, and the tourist is in the city 2. The museum there is open, but the tourist has already visited it. At night the tourist goes to the city number 3. 
  * Day 6. Now it's the 3rd day of a week, and the tourist is in the city 3. The museum there is open, and the tourist visits it. After this, the tour is over. 

Explanation of the second example <image>

The maximum number of distinct museums to visit is 2. It's possible to visit 2 museums, for example, in the way described below.

  * Day 1. Now it's the 1st day of a week, and the tourist is in the city 1. The museum there is open, and the tourist visits it. At night the tourist goes to the city number 2. 
  * Day 2. Now it's the 2nd day of a week, and the tourist is in the city 2. The museum there is closed. At night the tourist goes to the city number 3. 
  * Day 3. Now it's the 3rd day of a week, and the tourist is in the city 3. The museum there is open, and the tourist visits it. After this, the tour is over. 

### Response

```cpp
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma warning(disable : 4996)
using namespace std;
namespace Bigcat {
template <typename T>
inline void max_s(T& a, const T& b) {
  a = max(a, b);
}
template <typename T>
inline void min_s(T& a, const T& b) {
  a = min(a, b);
}
template <typename T>
void sort_v(T& x) {
  sort(x.begin(), x.end());
}
template <typename T>
void erase_dup(T& x) {
  x.erase(unique(x.begin(), x.end()), x.end());
}
template <typename T, typename V>
int pos_l(const T& x, const V& v) {
  return lower_bound(x.begin(), x.end(), v) - x.begin();
}
template <typename T, typename V>
int pos_u(const T& x, const V& v) {
  return upper_bound(x.begin(), x.end(), v) - x.begin();
}
inline unsigned rand_g() {
  static mt19937 mt_rand((int)time(0));
  return mt_rand();
}
using LL = long long;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<LL>;
using PII = pair<int, int>;
using VPII = vector<PII>;
}  // namespace Bigcat
using namespace Bigcat;
const LL base = LL(1e9 + 7);
const LL INFL = 1LL << 62;
const int INF = 1 << 30;
const int MAX = int(1e5 + 100);
const int MAX2 = MAX * 50;
int n, m, d;
VI gr[MAX];
VI stk;
int dfsn[MAX2];
int acc;
bool instk[MAX2];
int low[MAX2];
int color[MAX2];
int totColor;
void tarjan(int v) {
  low[v] = dfsn[v] = ++acc;
  stk.push_back(v);
  instk[v] = true;
  int nxd = (v % d + 1) % d;
  for (auto x : gr[v / d]) {
    int nx = x * d + nxd;
    if (dfsn[nx] == 0) {
      tarjan(nx);
      min_s(low[v], low[nx]);
    } else {
      if (instk[nx]) min_s(low[v], low[nx]);
    }
  }
  if (low[v] < dfsn[v]) return;
  while (true) {
    int t = stk.back();
    color[t] = totColor;
    stk.pop_back();
    instk[t] = false;
    if (t == v) break;
  }
  ++totColor;
}
string open[MAX];
vector<VI> ngr;
VI zs;
VI ss;
void solve1() {
  if (-1 > ngr.size()) {
    int x = 1;
  }
  LL result = 0;
  cin >> n >> m >> d;
  for (int i = 0; i < (int)(m); i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    gr[u].push_back(v);
  }
  memset(color, -1, sizeof(color));
  tarjan(0);
  for (int i = 0; i < (int)(n); i++) {
    cin >> open[i];
  }
  ngr.resize(totColor + 1);
  zs.resize(totColor + 1);
  ss.assign(totColor + 1, 0);
  for (int i = 0; i < (int)(n); i++) {
    set<int> t;
    for (int j = 0; j < (int)(d); j++) {
      if (open[i][j] == '1') t.insert(color[i * d + j]);
    }
    for (auto x : t) {
      if (x >= 0) zs[x]++;
    }
  }
  for (int i = 0; i < (int)(n * d); i++) {
    int nxd = (i % d + 1) % d;
    int c = color[i];
    if (c < 0) continue;
    for (auto x : gr[i / d]) {
      int nx = x * d + nxd;
      int c1 = color[nx];
      if (c1 < 0) continue;
      if (c == c1) continue;
      ngr[c].push_back(c1);
    }
  }
  for (int i = 0; i < (int)(totColor); i++) {
    for (auto x : ngr[i]) {
      max_s(ss[i], ss[x]);
    }
    ss[i] += zs[i];
  }
  auto x = max_element(ss.begin(), ss.end());
  result = *x;
  cout << result << endl;
}
void solve() {
  int t = 1;
  for (int i = 0; i < t; ++i) {
    solve1();
  }
  int x = 1;
}
void io_init() {
  const int inId = 0;
  const int outId = 0;
  if (inId > 0) {
    cerr << "redirect stdin to input " << inId << endl;
    string s = "input";
    s += to_string(inId);
    s += ".txt";
    auto r = freopen(s.c_str(), "r", stdin);
    if (r == nullptr) {
      cerr << "invalid input file " << s << endl;
      ;
      r = freopen("CON", "r", stdin);
    }
  }
  if (outId > 0) {
    cerr << "redirect stdout to stdout " << outId << endl;
    string s = "stdout";
    s += to_string(outId);
    s += ".txt";
    auto r = freopen(s.c_str(), "w", stdout);
    if (r == nullptr) {
      cerr << "invalid output file " << s << endl;
      ;
      r = freopen("CON", "w", stdout);
    }
  }
}
int main(int argc, char* argv[]) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(11);
  solve();
}

```