//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100007, D = 50;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

int comp[N * D];
pii comps[N * D];
int comp_iter = 0, comps_iter = 0;

int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    used[v] = gen;
    for (int u : g[v]) {
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

void gen_comp(int v) {
    used[v] = gen;
    comp[comp_iter++] = v;
    to_comp[v] = comps_iter;
    for (int u : ag[v]) {
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

char mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int i = comps[ind].first; i < comps[ind].second; ++i) {
        int v = comp[i];
        if (open[v] && !mus_usd[v / d]) {
            mus_usd[v / d] = 1;
            ++cnt;
        }
        for (int u : g[v]) {
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

int cur_t() {
    return clock() * 1000 / CLOCKS_PER_SEC;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[d * u + j].emplace_back((d * v) + ((j + 1) % d));
            ag[(d * v) + ((j + 1) % d)].emplace_back(d * u + j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;

    for (int v : top_srt) {
        if (used[v] == gen - 1) {
            comps[comps_iter].first = comp_iter;
            gen_comp(v);
            comps[comps_iter++].second = comp_iter;
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, char> pii;

int n, m, d;

const int N = 100007, D = 50;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
vector<int> top_srt;

vector<vector<int>> comps;
vector<int> comp;
int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    used[v] = gen;
    for (int u : g[v]) {
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt.emplace_back(v);
}

void gen_comp(int v) {
    used[v] = gen;
    comp.emplace_back(v);
    to_comp[v] = sz(comps);
    for (int u : ag[v]) {
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

char mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int v : comps[ind]) {
        if (open[v] && !mus_usd[v / d]) {
            mus_usd[v / d] = 1;
            ++cnt;
        }
    }
    for (int v : comps[ind]) {
        for (int u : g[v]) {
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[d * u + j].emplace_back((d * v) + ((j + 1) % d));
            ag[(d * v) + ((j + 1) % d)].emplace_back(d * u + j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    top_srt.reserve(n * d);

    ++gen;
    gen_srt(0);
    reverse(all(top_srt));
    ++gen;
    for (int v : top_srt) {
        if (used[v] != gen) {
            gen_comp(v);
            comps.emplace_back(comp);
            comp.clear();
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

const int N = 100047, D = 51;
vector<pii> g[N][D];
vector<pii> ag[N][D];
char used[N][D], gen;
vector<pii> top_srt;

vector<vector<pii>> comps;
vector<pii> comp;
int to_comp[N][D];

char open[N][D];
char comp_used[N * D];

void gen_srt(pii v) {
    used[v.first][v.second] = gen;
    for (pii u : g[v.first][v.second]) {
        if (used[u.first][u.second] != gen) {
            gen_srt(u);
        }
    }
    top_srt.emplace_back(v);
}

void gen_comp(pii v) {
    used[v.first][v.second] = gen;
    comp.emplace_back(v);
    to_comp[v.first][v.second] = sz(comps);
    for (pii u : g[v.first][v.second]) {
        if (used[u.first][u.second] != gen) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    set<int> opn;
    for (pii v : comps[ind]) {
        if (open[v.first][v.second]) {
            cnt += opn.insert(v.first).second;
        }
    }
    for (pii v : comps[ind]) {
        for (pii u : g[v.first][v.second]) {
            if (!comp_used[to_comp[u.first][u.second]]) {
                chkmax(nx, gen_dp(to_comp[u.first][u.second]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int n = input();
    int m = input();
    int d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[u][j].emplace_back(v, (j + 1) % d);
            ag[v][(j + 1) % d].emplace_back(u, j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[i][j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt({0, 0});
    reverse(all(top_srt));
    ++gen;
    for (pii v : top_srt) {
        if (used[v.first][v.second] != gen) {
            gen_comp(v);
            comps.emplace_back(comp);
            comp.clear();
        }
    }

    cout << gen_dp(to_comp[0][0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100047, D = 51;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

int comp[N * D];
pii comps[N * D];
int comp_iter = 0, comps_iter = 0;

int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    int vv = v / d, day = v % d;
//    assert(vv < N);
    used[v] = gen;
    for (int uu : g[vv]) {
        int u = d * uu + ((day + 1) % d);
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

int cur_t() {
    return clock() * 1000 / CLOCKS_PER_SEC;
}

void gen_comp(int v) {
    used[v] = gen;
    comp[comp_iter++] = v;
    to_comp[v] = comps_iter;
    int vv = v / d, day = v % d;
    for (int uu : ag[vv]) {
        int u = d * uu + ((day - 1 + d) % d);
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

bool mus_usd[N * D];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int i = comps[ind].first; i < comps[ind].second; ++i) {
        int v = comp[i];
        int vv = v / d, day = v % d;
        if (open[v] && !mus_usd[vv]) {
            mus_usd[vv] = true;
            ++cnt;
        }
        for (int uu : g[vv]) {
            int u = d * uu + ((day + 1) % d);
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

//    assert(n < N);
//    assert(m < N);
//    assert(d < D);

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
//        assert(u < N);
//        assert(v < N);
        g[u].emplace_back(v);
        ag[v].emplace_back(u);
    }

//    assert(cur_t() < 1200);

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;

    for (int v : top_srt) {
        if (used[v] == gen - 1) {
            comps[comps_iter].first = comp_iter;
            gen_comp(v);
            comps[comps_iter++].second = comp_iter;
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

const int N = 100047, D = 51;
vector<pii> g[N][D];
vector<pii> ag[N][D];
char used[N][D], gen;
vector<pii> top_srt;

vector<vector<pii>> comps;
vector<pii> comp;
int to_comp[N][D];
char open[N][D];
vector<char> comp_used;

void gen_srt(pii v) {
    used[v.first][v.second] = gen;
    for (pii u : g[v.first][v.second]) {
        if (used[u.first][u.second] != gen) {
            gen_srt(u);
        }
    }
    top_srt.emplace_back(v);
}

void gen_comp(pii v) {
    used[v.first][v.second] = gen;
    comp.emplace_back(v);
    to_comp[v.first][v.second] = sz(comps);
    for (pii u : ag[v.first][v.second]) {
        if (used[u.first][u.second] != gen) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    set<int> opn;
    for (pii v : comps[ind]) {
        if (open[v.first][v.second]) {
            cnt += opn.insert(v.first).second;
        }
    }
    for (pii v : comps[ind]) {
        for (pii u : g[v.first][v.second]) {
            if (!comp_used[to_comp[u.first][u.second]]) {
                chkmax(nx, gen_dp(to_comp[u.first][u.second]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int n = input();
    int m = input();
    int d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[u][j].emplace_back(v, (j + 1) % d);
            ag[v][(j + 1) % d].emplace_back(u, j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[i][j] = s[j] - '0';
        }
    }

    ++gen;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < d; ++j) {
            if (used[i][j] != gen) {
                gen_srt({i, j});
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < d; ++j) {
            ag[i][j].clear();
        }
    }
    reverse(all(top_srt));
    ++gen;
    for (pii v : top_srt) {
        if (used[v.first][v.second] != gen) {
            gen_comp(v);
            comps.emplace_back(comp);
            comp.clear();
        }
    }

    comp_used.resize(sz(comps));

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0][0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100007, D = 50;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

int comp[N * D];
pii comps[N * D];
int comp_iter = 0, comps_iter = 0;

int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    used[v] = gen;
    for (int u : g[v]) {
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

int cur_t() {
    return clock() * 1000 / CLOCKS_PER_SEC;
}

void gen_comp(int v) {
    assert(cur_t() < 1200);
    used[v] = gen;
    comp[comp_iter++] = v;
    to_comp[v] = comps_iter;
    for (int u : ag[v]) {
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

char mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int i = comps[ind].first; i < comps[ind].second; ++i) {
        int v = comp[i];
        if (open[v] && !mus_usd[v / d]) {
            mus_usd[v / d] = 1;
            ++cnt;
        }
        for (int u : g[v]) {
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[d * u + j].emplace_back((d * v) + ((j + 1) % d));
            ag[(d * v) + ((j + 1) % d)].emplace_back(d * u + j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;

    for (int v : top_srt) {
        if (used[v] == gen - 1) {
            comps[comps_iter].first = comp_iter;
            gen_comp(v);
            comps[comps_iter++].second = comp_iter;
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100007, D = 50;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

vector<int> comps[N * D];
int comp_iter = 0;
vector<int> comp;

int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    used[v] = gen;
    for (int u : g[v]) {
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

void gen_comp(int v) {
    used[v] = gen;
    comp.emplace_back(v);
    to_comp[v] = comp_iter;
    for (int u : ag[v]) {
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

char mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int v : comps[ind]) {
        if (open[v] && !mus_usd[v / d]) {
            mus_usd[v / d] = 1;
            ++cnt;
        }
    }
    for (int v : comps[ind]) {
        for (int u : g[v]) {
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[d * u + j].emplace_back((d * v) + ((j + 1) % d));
            ag[(d * v) + ((j + 1) % d)].emplace_back(d * u + j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;
    for (int v : top_srt) {
        if (used[v] != gen) {
            gen_comp(v);
            comps[comp_iter++] = move(comp);
            comp.clear();
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100047, D = 51;
vector<int> g[N], ag[N];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

int comp[N * D];
pii comps[N * D];
int comp_iter = 0, comps_iter = 0;

int to_comp[N * D];
char open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

char comp_used[N * D];

void gen_srt(int v) {
    int vv = v / d, day = v % d;
//    assert(vv < N);
    used[v] = gen;
    for (int uu : g[vv]) {
        int u = d * uu + ((day + 1) % d);
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

int cur_t() {
    return clock() * 1000 / CLOCKS_PER_SEC;
}

void gen_comp(int v) {
    used[v] = gen;
    comp[comp_iter++] = v;
    to_comp[v] = comps_iter;
    int vv = v / d, day = v % d;
    for (int uu : ag[vv]) {
        int u = d * uu + ((day - 1 + d) % d);
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

bool mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int i = comps[ind].first; i < comps[ind].second; ++i) {
        int v = comp[i];
        int vv = v / d, day = v % d;
        if (open[v] && !mus_usd[vv]) {
            mus_usd[vv] = true;
            ++cnt;
        }
        for (int uu : g[vv]) {
            int u = d * uu + ((day + 1) % d);
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

//    assert(n < N);
//    assert(m < N);
//    assert(d < D);

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
//        assert(u < N);
//        assert(v < N);
        g[u].emplace_back(v);
        ag[v].emplace_back(u);
    }

//    assert(cur_t() < 1200);

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;

    for (int v : top_srt) {
        if (used[v] == gen - 1) {
            comps[comps_iter].first = comp_iter;
            gen_comp(v);
            comps[comps_iter++].second = comp_iter;
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


//9:04

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()

#define ON

#ifdef ON
#define debug(x) cerr << #x << " = " << (x) << endl
#else
#define debug(x)
#endif

template<typename T = int>
T input() {
    T res;
    cin >> res;
    return res;
}

template<typename It>
void input_seq(It begin, It end, istream &in = cin) {
    generate(begin, end, input < typename remove_reference<decltype(*begin)>::type > );
}

template<class It>
void output(It begin, It end, ostream &out = cerr) {
    while (begin != end) {
        out << *(begin++) << ' ';
    }
    out << endl;
}

typedef pair<int, int> pii;

int n, m, d;

const int N = 100007, D = 51;
vector<int> g[N * D], ag[N * D];
char used[N * D], gen;
int top_srt[N * D], iter = 0;

int comp[N * D];
pii comps[N * D];
int comp_iter = 0, comps_iter = 0;

int to_comp[N * D];
bool open[N * D];

//vector<pii> g[N][D];
//vector<pii> ag[N][D];
//char used[N][D], gen;
//vector<pii> top_srt;

//vector<vector<pii>> comps;
//vector<pii> comp;
//int to_comp[N][D];
//char open[N][D];

bool comp_used[N * D];

void gen_srt(int v) {
    used[v] = gen;
    for (int u : g[v]) {
        if (used[u] != gen) {
            gen_srt(u);
        }
    }
    top_srt[iter++] = v;
}

int cur_t() {
    return clock() * 1000 / CLOCKS_PER_SEC;
}

void gen_comp(int v) {
    used[v] = gen;
    comp[comp_iter++] = v;
    to_comp[v] = comps_iter;
    for (int u : ag[v]) {
        if (used[u] == gen - 1) {
            gen_comp(u);
        }
    }
}

template <typename T>
void chkmax(T &x, T y) {
    if (x < y) {
        x = y;
    }
}

bool mus_usd[N];

int gen_dp(int ind) {
    comp_used[ind] = true;
    int cnt = 0, nx = 0;
    for (int i = comps[ind].first; i < comps[ind].second; ++i) {
        int v = comp[i];
        if (open[v] && !mus_usd[v / d]) {
            mus_usd[v / d] = 1;
            ++cnt;
        }
        for (int u : g[v]) {
            if (!comp_used[to_comp[u]]) {
                chkmax(nx, gen_dp(to_comp[u]));
            }
        }
    }
    return cnt + nx;
}

signed main() {
#ifdef ON
    //    freopen("../in.txt", "r", stdin);
    //    freopen("../out.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    n = input();
    m = input();
    d = input();

    assert(n < N);
    assert(m < N);
    assert(d < D);

    for (int i = 0; i < m; ++i) {
        int u = input() - 1;
        int v = input() - 1;
        for (int j = 0; j < d; ++j) {
            g[d * u + j].push_back((d * v) + ((j + 1) % d));
            ag[(d * v) + ((j + 1) % d)].push_back(d * u + j);
        }
    }

    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        for (int j = 0; j < d; ++j) {
            open[d * i + j] = s[j] - '0';
        }
    }

    assert(cur_t() < 1200);

    ++gen;
    gen_srt(0);
    reverse(top_srt, top_srt + (D * N));
    ++gen;

    for (int v : top_srt) {
        if (used[v] == gen - 1) {
            comps[comps_iter].first = comp_iter;
            gen_comp(v);
            comps[comps_iter++].second = comp_iter;
        }
    }

//    for (auto &c : comps) {
//        cerr << "comp: ";
//        for (pii &k : c) {
//            cerr << k.first << ":" << k.second << ' ';
//        }
//        cerr << endl;
//    }

    cout << gen_dp(to_comp[0]) << endl;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], abs(dep[u] - dep[v] + 1));
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        assert(per[i] > 0);
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(auto &v : G[i]){

            if(bel[i] == bel[v]) continue;
            P[bel[v]].pb(bel[i]);
            ++in[bel[i]];
        }
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 0; i < lim; ++i) if(!in[i]) q.push(i);
    while(!q.empty()){

        int u = q.front(); q.pop();
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(auto &v : P[u]){

            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) q.push(v);
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], abs(dep[u] - dep[v] + 1));
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v);
        while(v != u);
        per[tot] = d, dfs(u, 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        assert(per[i] > 0);
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] - dep[v] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < n; ++i) dep[i] %= per[bel[i]];
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = j + dep[v]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    int dv = (j + dep[v] + 1) % per[i];
                    dp[i][j] = max(dp[i][j], dp[bel[v]][dv] + wi[i][j]);
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] > dep[v] ? dep[u] - dep[v] + 1 : dep[v] - dep[u] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        assert(per[i] > 0);
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn], edge2[maxn];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn], vis[100005];
int dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i) dfn[i] = 0;
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++dfn[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!dfn[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--dfn[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn], edge2[maxn];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn], vis[100005];
int dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i) dfn[i] = 0;
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++dfn[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!dfn[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--dfn[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

     int size = 128 << 20; // 512MB
    char *p = (char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p));
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn << 1], edge2[maxn << 1];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn], vis[100005];
int dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++in[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] > dep[v] ? dep[u] - dep[v] + 1 : dep[v] - dep[u] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v);
        while(v != u);
        per[tot] = d, dfs(u, 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        assert(per[i] > 0);
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
struct Edge{
    int v, nxt;
} edge[maxn << 1], edge2[maxn << 1];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++in[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] - dep[v] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] - dep[v] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < n; ++i) dep[i] %= per[bel[i]];
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                for(int k = j + dep[v]; k < d; k += per[i]){

                    wi[i][j] += tag[v][k];
                }
            }
        }
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
        // cout << i << " ?? " << wi[i][0] << endl;
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    int dv = (j + dep[v] + 1) % per[i];
                    dp[i][j] = max(dp[i][j], dp[bel[v]][dv] + wi[i][j]);
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn], edge2[maxn];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn], vis[100005];
int dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i) dfn[i] = 0;
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++dfn[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!dfn[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--dfn[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

     int size = 512 << 20; // 512MB
    char *p = (char*)malloc(size) + size;
    __asm__("movl %0, %%esp\n" :: "r"(p));
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e2 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(auto &v : G[i]){

            if(bel[i] == bel[v]) continue;
            P[bel[v]].pb(bel[i]);
            ++in[bel[i]];
        }
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) q.push(i);
    while(!q.empty()){

        int u = q.front(); q.pop();
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(auto &v : P[u]){

            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) q.push(v);
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] - dep[v] + 1), assert(dep[u] > dep[v]);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < per[i]; ++j){

            for(auto &v : scc[i]){

                int flg = 0;
                for(int k = (j + dep[v]) % per[i]; !flg && k < d; k += per[i]){

                    flg |= tag[v][k];
                }
                wi[i][j] += flg;
            }
        }
        assert(per[i] > 0);
        for(int j = per[i]; j < d; ++j) wi[i][j] = wi[i][j - per[i]];
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    for(int k = (j + dep[u] + 1) % per[i]; k < d; k += per[i]){

                        dp[i][j] = max(dp[i][j], dp[bel[v]][k] + wi[i][j]);
                    }
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn << 1], edge2[maxn << 1];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn], vis[100005];
int dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 1; i <= tot; ++i) dfn[i] = 0;
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++dfn[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!dfn[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--dfn[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], pi;
struct Edge{
    int v, nxt;
} edge[maxn];
int head[maxn], cnt;
bool ins[maxn], tag[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn];
int wi[maxn], dp[maxn];
int n, m, d, tot, top, tim;

void add(int u, int v){

    edge[++cnt] = { v, head[u] }, head[u] = cnt;
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; pi.clear();
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v]) pi.pb(v % n);
        }
        while(v != u);
        sort(pi.begin(), pi.end());
        pi.erase(unique(pi.begin(), pi.end()), pi.end());
        wi[tot++] += sz(pi);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        for(int j = 0; j < d; ++j){

            add(u + j * n, v + (j + 1) % d * n);
        }
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i + j * n] = s[j] - '0';
    }
    int tn = n * d;
    for(int i = 0; i < tn; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < tn; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            G[bel[i]].pb(bel[v]);
        }
    }
    for(int i = 0; i < tot; ++i){

        dp[i] += wi[i];
        for(auto &v : G[i]) dp[i] = max(dp[i], dp[v] + wi[i]);
    }
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
struct Edge{
    int v, nxt;
} edge[maxn << 1], edge2[maxn << 1];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++in[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int que[maxn], ql, qr;
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(auto &v : G[i]){

            if(bel[i] == bel[v]) continue;
            P[bel[v]].pb(bel[i]);
            ++in[bel[i]];
        }
        G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(auto &v : P[u]){

            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

vector<int> G[maxn], scc[maxn];
bool tag[maxn][55];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], rt[maxn];
int wi[maxn][55], dp[maxn][55], dep[maxn], per[maxn], vis[maxn];
int n, m, d, tot, top, tim;

int gcd(int a, int b){

    return b ? gcd(b, a % b) : a;
}

void dfs(int u, int dd){

    vis[u] = 1, dep[u] = dd;
    for(auto &v : G[u]){

        if(bel[v] != bel[u]) continue;
        if(!vis[v]) dfs(v, dep[v] = dep[u] + 1);
        else per[bel[u]] = gcd(per[bel[u]], dep[u] - dep[v] + 1);
    }
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim, stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot; rt[tot] = u;
        do v = stk[top--], ins[v] = 0, bel[v] = tot, scc[tot].pb(v), rt[tot] = min(rt[tot], v);
        while(v != u);
        per[tot] = d, dfs(rt[tot], 0);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 1; i <= m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        G[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        char s[233]; cin >> s;
        for(int j = 0; j < d; ++j) tag[i][j] = s[j] - '0';
    }
    for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < n; ++i) dep[i] %= per[bel[i]];
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            for(auto &v : scc[i]){

                wi[i][j] += tag[v][(j + dep[v]) % per[i]];
            }
        }
        // cout << i << " ?? " << wi[i][0] << endl;
    }
    for(int i = 1; i <= tot; ++i){

        for(int j = 0; j < d; ++j){

            dp[i][j] = wi[i][j];
            for(auto &u : scc[i]){

                for(auto &v : G[u]){

                    if(bel[v] == bel[u]) continue;
                    int dv = (j + dep[v] + 1) % per[i];
                    dp[i][j] = max(dp[i][j], dp[bel[v]][dv] + wi[i][j]);
                }
            }
        }
    }
    cout << dp[bel[0]][0] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e3 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int vis[maxn], tag[maxn], ans[maxn];
int n, m, d;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
}

void dfs(int u){

    vis[u] = 1, ans[u % n] += tag[u];
    for(auto &v : G[u]){

        if(vis[v]) continue;
        dfs(v);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    dfs(0);
    int ret = 0;
    for(int i = 0; i < n; ++i) ret += ans[i] > 0;
    cout << ret << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int vis[maxn], tag[maxn], ans[maxn];
int n, m, d;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
}

void dfs(int u){

    vis[u] = 1, ans[u % n] += tag[u];
    for(auto &v : G[u]){

        if(vis[v]) continue;
        dfs(v);
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    dfs(0);
    int ret = 0;
    for(int i = 0; i < n; ++i) ret += ans[i] > 0;
    cout << ret << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
vector<int> G[maxn], P[maxn];
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(auto &v : G[u]){

        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(auto &v : G[i]){

            if(bel[i] == bel[v]) continue;
            P[bel[v]].pb(bel[i]);
            ++in[bel[i]];
        }
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) q.push(i);
    while(!q.empty()){

        int u = q.front(); q.pop();
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(auto &v : P[u]){

            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) q.push(v);
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[maxn];
struct Edge{
    int v, nxt;
} edge[maxn << 1];
int head[maxn], eCnt;
vector<int> P[maxn];
int que[maxn], ql, qr;
int vis[maxn], tag[maxn], dp[maxn], wi[maxn], rub[maxn];
int dfn[maxn], low[maxn], stk[maxn], ins[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v] && !vis[v % n]) rub[++cnt] = v, vis[v % n] = 1, ++wi[tot];
        }
        while(v != u);
        while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            P[bel[v]].pb(bel[i]);
            ++in[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    queue<int> q;
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(auto &v : P[u]){

            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 5e6 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

char s[233];
struct Edge{
    int v, nxt;
} edge[maxn << 1], edge2[maxn << 1];
vector<int> P[100005];
int head[maxn], eCnt, head2[maxn], eCnt2;
int que[maxn], ql, qr;
bool tag[maxn], ins[maxn];
int dp[maxn], wi[maxn];
int dfn[maxn], low[maxn], stk[maxn], bel[maxn], in[maxn];
int n, m, d, tot, tim, top, cnt;

void add(int u, int v){

    edge[++eCnt] = {v, head[u]}, head[u] = eCnt;
}

void add2(int u, int v){

    edge2[++eCnt2] = {v, head2[u]}, head2[u] = eCnt2;
}

void build(){

    for(int now = 0; now < d; ++now){

        int nxt = (now + 1) % d;
        for(int i = 0; i < n; ++i){

            for(auto &v : P[i]){

                add(i + now * n, v + nxt * n);
                // G[i + now * n].pb(v + nxt * n);
            }
        }
    }
    for(int i = 0; i < n; ++i) P[i].clear();
}

void tarjan(int u){

    dfn[u] = low[u] = ++tim; stk[++top] = u, ins[u] = 1;
    for(int i = head[u]; i; i = edge[i].nxt){

        int v = edge[i].v;
        if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
        else if(ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u]){

        int v; ++tot;
        do{

            v = stk[top--], ins[v] = 0, bel[v] = tot;
            if(tag[v]) ++wi[tot];
        }
        while(v != u);
        // while(cnt > 0) vis[rub[cnt--] % n] = 0;
    }
}

void solve(){

    int lim = n * d;
    for(int i = 0; i < lim; ++i) if(!dfn[i]) tarjan(i);
    for(int i = 0; i < lim; ++i){

        for(int j = head[i]; j; j = edge[j].nxt){

            int v = edge[j].v;
            if(bel[i] == bel[v]) continue;
            // P[bel[v]].pb(bel[i]);
            add2(bel[v], bel[i]);
            ++in[bel[i]];
        }
        // G[i].clear();
    }
    // for(int i = 0; i < lim; ++i){

    //     cout << i << " " << i % n << " " << bel[i] << " " << wi[bel[i]] << endl;
    // }
    for(int i = 1; i <= tot; ++i) if(!in[i]) que[qr++] = i;
    while(ql < qr){

        int u = que[ql++];
        dp[u] += wi[u];
        // cout << u << " " << wi[u] << " " << dp[u] << endl;
        for(int i = head2[u]; i; i = edge2[i].nxt){

            int v = edge2[i].v;
            dp[v] = max(dp[v], dp[u]);
            if(--in[v] == 0) que[qr++] = v;
        }
    }
}

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m >> d;
    for(int i = 0; i < m; ++i){

        int u, v; cin >> u >> v; --u, --v;
        P[u].pb(v);
    }
    for(int i = 0; i < n; ++i){

        cin >> s;
        for(int j = 0; j < d; ++j){

            tag[i + n * j] = s[j] - '0';
        }
    }
    build();
    solve();
    cout << dp[bel[0]] << endl;
    return 0;
}


/*
Julia M.(aka Andrei Konstantinovich)
*/
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
#define int long long

#define x first
#define y second
#define ll long long
#define pii pair<int, int>
#define ld long double
const int MN = 1e5 + 1, MD = 50;
vector<int> g[MN], gr[MN];
vector<int> gc[MN * MD], sz[MN * MD];
string op[MN];
char us[MN * MD];
int pt[MN * MD], col[MN * MD], szc[MN * MD], t = 0;
inline void dfs(int u, int d)
{
    us[u] = 1;
    int t = u / d, p = u % d;
    for (int k : g[t])
    {
        int v = k * d + (p + 1) % d;
        if (!us[v])
            dfs(v, d);
    }
    pt[::t++] = u;
}
inline void dfs2(int u, int d, int c)
{
    col[u] = c;
    sz[c].push_back(u);
    int t = u / d, p = u % d;
    for (auto k : gr[t])
    {
        int v = k * d + (p - 1 + d) % d;
        if (!col[v])
            dfs2(v, d, c);
    }
}

int dp[MN * MD];
inline void dfs3(int u)
{
    us[u] = 1;
    for (auto c : gc[u])
    {
        if (!us[c])
            dfs3(c);
        dp[u] = max(dp[u], dp[c]);
    }
    dp[u] += szc[u];
}

int32_t main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int n, m, d;
    cin >> n >> m >> d;
    for (int i = 0; i < m; ++i)
    {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        g[u].push_back(v);
        gr[v].push_back(u);
    }
    for (int i = 0; i < n; ++i)
    {
        cin >> op[i];
    }

    for (int i = 0; i < n * d; ++i)
    {
        if (!us[i])
            dfs(i, d);
    }

    reverse(pt, pt + t);
    int c = 1;
    for (int i = 0; i < t; ++i)
    {
        if (!col[pt[i]])
            dfs2(pt[i], d, c++);
    }

    memset(us, 0, sizeof(us));
    for (int i = 1; i < c; ++i)
    {
        for (auto u : sz[i])
        {
            if (!us[u / d] && (op[u / d][u % d] == '1'))
            {
                szc[i]++;
                us[u / d] = 1;
            }
        }
        for (auto u : sz[i])
        {
            us[u / d] = 0;
        }
    }

    if (n == 99998)
        assert(0);
    for (int u = 0; u < n; ++u)
    {
        for (int c = 0; c < d; ++c)
        {
            int cn = (c + 1) % d;
            for (auto v : g[u])
            {
                if (col[u * d + c] != col[v * d + cn])
                {
                    gc[col[u * d + c]].push_back(col[v * d + cn]);
                }
            }
        }
    }

    dfs3(col[0]);
    cout << dp[col[0]];
}