//
//  main.cpp
//  Algorithm
//
//  Created by Luke Lee on 2015. 12. 25..
//  Copyright (c) 2015년 Luke Lee. All rights reserved.
//

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = {y, x};
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back({y, x});
                for (_coord v = next_move[y][x]; v != cur; v = next_move[v.y][v.x])
                {
                    in_cycle[v.y][v.x] = true;
                    cycle_idx[v.y][v.x] = cycle_n;
                    cycle[cycle_n].contained[table[v.y][v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        size_t l = s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, (int)l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = (int)l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                if (start_p == (int)l)
                {
                    yes = true;
                    break;
                }

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    if (track_remainder(v, start_p, s))
                    {
                        yes = true;
                        break;
                    }
                }
                if (yes) break;
            }
            if (yes) break;
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    size_t l = s.size();

    p += (table[u.y][u.x] == s[p]);
    if (p == l)
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


//
//  E. Wilbur and Strings.cpp
//  Codeforces - Codeforces Round #331 (Div. 2)
//
//  Created by Luke Lee on 2015. 12. 22..
//  Copyright (c) 2015년 Luke Lee. All rights reserved.
//

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = {y, x};
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back({y, x});
                for (_coord v = next_move[y][x]; v != cur; v = next_move[v.y][v.x])
                {
                    in_cycle[v.y][v.x] = true;
                    cycle_idx[v.y][v.x] = cycle_n;
                    cycle[cycle_n].contained[table[v.y][v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        int l = (int)s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                yes |= (start_p == l);

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    yes |= track_remainder(v, start_p, s);
                }
            }
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    size_t l = s.size();

    p += (table[u.y][u.x] == s[p]);
    if (p == l)
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


//
//  main.cpp
//  Algorithm
//
//  Created by Luke Lee on 2015. 12. 22..
//  Copyright (c) 2015년 Luke Lee. All rights reserved.
//

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = {y, x};
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back({y, x});
                for (_coord v = next_move[y][x]; v != cur; v = next_move[v.y][v.x])
                {
                    in_cycle[v.y][v.x] = true;
                    cycle_idx[v.y][v.x] = cycle_n;
                    cycle[cycle_n].contained[table[v.y][v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        size_t l = s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, (int)l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = (int)l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                if (start_p == l)
                {
                    yes = true;
                    break;
                }

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    if (track_remainder(v, start_p, s))
                    {
                        yes = true;
                        break;
                    }
                }
                if (yes) break;
            }
            if (yes) break;
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    size_t l = s.size();

    p += (table[u.y][u.x] == s[p]);
    if (p == l)
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


//
//  main.cpp
//  Algorithm
//
//  Created by Luke Lee on 2016. 2. 2..
//  Copyright (c) 2016년 Luke Lee. All rights reserved.
//

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = cur;
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (visited[y][x]) continue;

            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back(cur);
                for (_coord next_v = next_move[y][x]; next_v != cur; next_v = next_move[next_v.y][next_v.x])
                {
                    in_cycle[next_v.y][next_v.x] = true;
                    cycle_idx[next_v.y][next_v.x] = cycle_n;
                    cycle[cycle_n].contained[table[next_v.y][next_v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(next_v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        int l = (int)s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = (int)l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                yes |= (start_p == l);

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    yes |= track_remainder(v, start_p, s);
                }
            }
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    p += (table[u.y][u.x] == s[p]);

    if (p == (int)s.size())
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


//
//  main.cpp
//  Algorithm
//
//  Created by Luke Lee on 2016. 2. 2..
//  Copyright (c) 2016년 Luke Lee. All rights reserved.
//

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = {y, x};
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (visited[y][x]) continue;

            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back(cur);
                for (_coord next_v = next_move[y][x]; next_v != cur; next_v = next_move[next_v.y][next_v.x])
                {
                    in_cycle[next_v.y][next_v.x] = true;
                    cycle_idx[next_v.y][next_v.x] = cycle_n;
                    cycle[cycle_n].contained[table[next_v.y][next_v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(next_v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        size_t l = s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = (int)l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                yes |= (start_p == l);

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    yes |= track_remainder(v, start_p, s);
                }
            }
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    p += (table[u.y][u.x] == s[p]);

    if (p == (int)s.size())
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>

#define SIZE 200
#define L 1000000

using namespace std;

struct _coord
{
    int y, x;

    _coord operator +(const _coord& right)
    {
        y += right.y;
        x += right.x;
        return *this;
    }
    _coord operator +=(const _coord& right)
    {
        return *this + right;
    }
    bool operator !=(const _coord& comp) const
    {
        return y != comp.y || x != comp.x;
    }
};

typedef vector<_coord> _coord_v;

struct cycle_t
{
    int contained[10];
    _coord_v cycle_list;
};

typedef vector<cycle_t> cycle_t_v;

char table[SIZE + 2][SIZE + 2];
_coord d[10];
char _s[L + 1];

_coord next_move[SIZE + 2][SIZE + 2];
bool in_cycle[SIZE + 2][SIZE + 2], visited[SIZE + 2][SIZE + 2];
int cycle_idx[SIZE + 2][SIZE + 2];
int cycle_n;

cycle_t_v cycle;

_coord_v origin[SIZE + 2][SIZE + 2];

void dfs_cycle(_coord);
bool track_remainder(_coord, int, string&);

int main(int argc, const char * argv[])
{
    // insert code here...
    int size_y, size_x, m;
    scanf("%d%d%d", &size_y, &size_x, &m);
    for (int y = 1; y <= size_y; y++)
    {
        scanf("%s", table[y] + 1);
    }
    for (int i = 0; i < 10; i++)
    {
        scanf("%d%d", &d[i].y, &d[i].x);
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            next_move[y][x] = cur + d[table[y][x] - '0'];
            if (next_move[y][x].y < 1 || next_move[y][x].y > size_y || next_move[y][x].x < 1 || next_move[y][x].x > size_x)
            {
                next_move[y][x] = {y, x};
            }
        }
    }
    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            _coord cur = {y, x};
            dfs_cycle(cur);
            if (in_cycle[y][x] && !cycle_idx[y][x])
            {
                cycle_t tmp;
                cycle.push_back(tmp);

                cycle_idx[y][x] = cycle_n;
                cycle[cycle_n].contained[table[y][x] - '0'] = true;
                cycle[cycle_n].cycle_list.push_back({y, x});
                for (_coord next_v = next_move[y][x]; next_v != cur; next_v = next_move[next_v.y][next_v.x])
                {
                    in_cycle[next_v.y][next_v.x] = true;
                    cycle_idx[next_v.y][next_v.x] = cycle_n;
                    cycle[cycle_n].contained[table[next_v.y][next_v.x] - '0'] = true;
                    cycle[cycle_n].cycle_list.push_back(next_v);
                }
                cycle_n++;
            }
        }
    }

    for (int y = 1; y <= size_y; y++)
    {
        for (int x = 1; x <= size_x; x++)
        {
            if (in_cycle[y][x]) continue;

            origin[next_move[y][x].y][next_move[y][x].x].push_back({y, x});
        }
    }

    while (m--)
    {
        scanf("%s", _s);

        string s = _s;
        reverse(s.begin(), s.end());
        size_t l = s.size();

        int first_appear[10];
        fill(first_appear, first_appear + 10, (int)l);
        for (int i = 0; i < l; i++)
        {
            first_appear[s[i] - '0'] = min(first_appear[s[i] - '0'], i);
        }

        bool yes = false;
        for (int y = 1; y <= size_y; y++)
        {
            for (int x = 1; x <= size_x; x++)
            {
                if (!in_cycle[y][x]) continue;

                int start_p = (int)l;
                for (int i = 0; i < 10; i++)
                {
                    if (first_appear[i] == l) continue;

                    if (!cycle[cycle_idx[y][x]].contained[i])
                    {
                        start_p = min(start_p, first_appear[i]);
                    }
                }
                if (start_p == l)
                {
                    yes = true;
                    break;
                }

                for (auto v : cycle[cycle_idx[y][x]].cycle_list)
                {
                    if (track_remainder(v, start_p, s))
                    {
                        yes = true;
                        break;
                    }
                }
            }
            if (yes) break;
        }

        printf("%s\n", yes ? "YES" : "NO");
    }

    return 0;
}

void dfs_cycle(_coord u)
{
    if (visited[u.y][u.x])
    {
        in_cycle[u.y][u.x] = true;
        return;
    }
    visited[u.y][u.x] = true;

    dfs_cycle(next_move[u.y][u.x]);
}

bool track_remainder(_coord u, int p, string& s)
{
    size_t l = s.size();

    p += (table[u.y][u.x] == s[p]);
    if (p == l)
    {
        return true;
    }

    for (_coord v : origin[u.y][u.x])
    {
        if (track_remainder(v, p, s))
        {
            return true;
        }
    }

    return false;
}


//*
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <numeric>
#include <functional>
#define MOD 1000000007
#define MAX ((1<<30)-1)
#define MAX2 ((1ll<<62)-1)
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define comp(x, y) ((x)*m+(y))
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

int n, m, q;
char a[300][300];
pii dat[20];
string b[400];
int d[50000];
char in[2000000];
int nex[50000];
int check[50000];
vector<int> edge[100000];
int group[50000];
int groupi;
int gdat[50000][10];
int qdat[10];

int suc;

int isgood(int x, int y)
{
	return x>=0&&y>=0&&x<n&&y<m;
}

void back(int now, int x, int y)
{
	if(b[x][y]-'0' == d[now-50000]) y--;
	if(y == -1)
	{
		suc=1;
		return;
	}
	for(auto e : edge[now]) back(e, x, y);
}

int main()
{
	int i, j, k;
	cin>>n>>m>>q;
	for(i=0;i<n;i++) scanf("%s", a[i]);
	for(i=0;i<10;i++) scanf("%d%d", &dat[i].first, &dat[i].second);
	for(i=0;i<q;i++) scanf("%s", in), b[i]=string(in);
	for(i=0;i<n;i++) for(j=0;j<m;j++)
	{
		int x=a[i][j]-'0';
		d[comp(i, j)]=x;
		if(isgood(i+dat[x].first, j+dat[x].second)) nex[comp(i, j)]=comp(i+dat[x].first, j+dat[x].second);
		else nex[comp(i, j)]=comp(i, j);
	}
	n=n*m;
	groupi=-1;
	memset(group, -1, sizeof(group));
	for(i=0;i<n;i++)
	{
		if(check[i]) continue;
		vector<int> q;
		q.push_back(i);
		check[i]=1;
		for(j=0;j<q.size();j++)
		{
			int now=q[j];
			if(check[nex[now]])
			{
				int flag=0;
				for(auto e : q)
				{
					if(e == nex[now])
					{
						flag=1;
						++groupi;
					}
					if(flag) group[e]=groupi, gdat[groupi][d[e]]=1;
				}
			}
			else
			{
				q.push_back(nex[now]);
				check[nex[now]]=1;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		if(group[i] != -1) continue;
		int u=group[nex[i]]==-1?nex[i]+50000:group[nex[i]];
		edge[u].push_back(i+50000);
	}
	groupi++;
	for(i=0;i<q;i++)
	{
		suc=0;
		memset(qdat, -1, sizeof(qdat));
		for(j=0;j<b[i].size();j++) qdat[b[i][j]-'0']=j;
		for(j=0;j<groupi;j++)
		{
			int ma=-1;
			for(k=0;k<10;k++)
			{
				if(gdat[j][k]) continue;
				if(qdat[k] == -1) continue;
				ma=max(ma, qdat[k]);
			}
			if(ma == -1)
			{
				suc=1;
				break;
			}
			for(auto e : edge[j])
			{
				back(e, i, ma);
			}
		}
		printf(suc==0?"NO\n":"YES\n");
	}
	return 0;
}
//*/


//*
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <numeric>
#include <functional>
#define MOD 1000000007
#define MAX ((1<<30)-1)
#define MAX2 ((1ll<<62)-1)
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define comp(x, y) ((x)*m+(y))
#pragma warning(disable:4996)
using namespace std;

typedef long long ll;
typedef long double ldb;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;

int n, m, q;
char a[300][300];
pii dat[20];
string b[400];
int d[50000];
char in[2000000];
int nex[50000];
int check[50000];
vector<int> edge[100000];
int group[50000];
int groupi;
int gdat[50000][10];
int qdat[10];

int suc;

int isgood(int x, int y)
{
	return x>=0&&y>=0&&x<n&&y<m;
}

void back(int now, int x, int y)
{
	if(b[x][y] == d[now-50000]) y--;
	if(y == -1)
	{
		suc=1;
		return;
	}
	for(auto e : edge[now]) back(e, x, y);
}

int main()
{
	int i, j, k;
	cin>>n>>m>>q;
	for(i=0;i<n;i++) scanf("%s", a[i]);
	for(i=0;i<10;i++) scanf("%d%d", &dat[i].first, &dat[i].second);
	for(i=0;i<q;i++) scanf("%s", in), b[i]=string(in);
	for(i=0;i<n;i++) for(j=0;j<m;j++)
	{
		int x=a[i][j]-'0';
		d[comp(i, j)]=x;
		if(isgood(i+dat[x].first, j+dat[x].second)) nex[comp(i, j)]=comp(i+dat[x].first, j+dat[x].second);
		else nex[comp(i, j)]=comp(i, j);
	}
	n=n*m;
	groupi=-1;
	memset(group, -1, sizeof(group));
	for(i=0;i<n;i++)
	{
		if(check[i]) continue;
		vector<int> q;
		q.push_back(i);
		check[i]=1;
		for(j=0;j<q.size();j++)
		{
			int now=q[j];
			if(check[nex[now]])
			{
				int flag=0;
				for(auto e : q)
				{
					if(e == nex[now])
					{
						flag=1;
						++groupi;
					}
					if(flag) group[e]=groupi, gdat[groupi][d[e]]=1;
				}
			}
			else
			{
				q.push_back(nex[now]);
				check[nex[now]]=1;
			}
		}
	}
	for(i=0;i<n;i++)
	{
		if(group[i] != -1) continue;
		int u=group[nex[i]]==-1?nex[i]+50000:nex[i];
		edge[u].push_back(i+50000);
	}
	groupi++;
	for(i=0;i<q;i++)
	{
		suc=0;
		memset(qdat, -1, sizeof(qdat));
		for(j=0;j<b[i].size();j++) qdat[b[i][j]-'0']=j;
		for(j=0;j<groupi;j++)
		{
			int ma=-1;
			for(k=0;k<10;k++)
			{
				if(gdat[j][k]) continue;
				if(qdat[k] == -1) continue;
				ma=max(ma, qdat[k]);
			}
			if(ma == -1)
			{
				suc=1;
				break;
			}
			for(auto e : edge[j])
			{
				back(e, i, ma);
			}
		}
		printf(suc==0?"NO\n":"YES\n");
	}
	return 0;
}
//*/


#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    int n,odd=0,even=0;
    cin>>n;
    int a[n];
    int b[n];
    for(int i=0;i<n;i++)
        cin>>a[i];

    for(int i=0;i<n;i++)
    {
        if(a[i]%2==0)
            {
                b[i]=0;
                odd++;
            }

        else
        {
        even++;
        b[i]=1;
    }
    }
        if(even==1)
        {
            for(int i=0;i<n;i++)
            {
                if(a[i]%2!=0)
                {

                    cout<<i+1;
                    return 0;
            }
            }
        }
        if(odd==1)
        {
            for(int i=0;i<n;i++)
            {
                if(a[i]%2==0)
                {

                    cout<<i+1;
                    return 0;
            }
            }
        }

}


#include <bits/stdc++.h>

using namespace std;

const int N = 1234567;

vector <int> rev[N];
char foo[N];
int on_cycle[N];
int digit[N], to[N];

bool found;

void dfs(int v, int pos) {
  if (pos < 0) {
    found = true;
  }
  if (found) {
    return;
  }
  int sz = rev[v].size();
  for (int j = 0; j < sz; j++) {
    int u = rev[v][j];
    if (on_cycle[u] != -1) {
      continue;
    }
    dfs(u, pos - (digit[u] == foo[pos] - '0'));
  }
}

int dx[42], dy[42];
int last[42];
bool vis[N];

const int NNN = 444;

char s[NNN][NNN];

int main() {
  int n, m, q;
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 0; i < n; i++) {
    scanf("%s", s[i]);
  }
  for (int d = 0; d <= 9; d++) {
    scanf("%d %d", dx + d, dy + d);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      int d = s[i][j] - '0';
      int x = i + dx[d];
      int y = j + dy[d];
      if (x < 0 || y < 0 || x >= n || y >= m) {
        x = i;
        y = j;
      }
      digit[i * m + j] = d;
      to[i * m + j] = x * m + y;
    }
  }
  n = n * m;
  for (int i = 0; i < n; i++) {
    vis[i] = false;
    rev[i].clear();
    on_cycle[i] = -1;
  }
  for (int i = 0; i < n; i++) {
    rev[to[i]].push_back(i);
  }
  for (int i = 0; i < n; i++) {
    if (vis[i]) {
      continue;
    }
    int p = i;
    vector <int> cycle;
    while (!vis[p]) {
      cycle.push_back(p);
      vis[p] = true;
      p = to[p];
    }
    int id = -1;
    for (int i = 0; i < (int)cycle.size(); i++) {
      if (cycle[i] == p) {
        id = i;
        break;
      }
    }
    if (id == -1) {
      continue;
    }
    int mask = 0;
    for (int i = id; i < (int)cycle.size(); i++) {
      mask |= (1 << digit[cycle[i]]);
    }
    for (int i = id; i < (int)cycle.size(); i++) {
      on_cycle[cycle[i]] = mask;
    }
  }
  while (q--) {
    scanf("%s", foo);
    int len = strlen(foo);
    for (int d = 0; d <= 9; d++) {
      last[d] = -1;
    }
    for (int i = 0; i < len; i++) {
      last[foo[i] - '0'] = i;
    }
    found = false;
    for (int start = 0; start < n; start++) {
      if (on_cycle[start] == -1) {
        continue;
      }
      int pos = -1;
      for (int d = 0; d <= 9; d++) {
        if (on_cycle[start] & (1 << d)) {
          continue;
        }
        pos = max(pos, last[d]);
      }
      dfs(start, pos);
    }
    puts(found ? "YES" : "NO");
  }
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W,Q;
string S,T;
int DY[10],DX[10];

int nex[202*202];
int inloop[202*202];
int vis[202*202];
int mask[202*202];
vector<int> st;
vector<int> E[202*202];
int first[10];

int dfs(int cur,int first) {
	vis[cur]=first;
	if(vis[nex[cur]]==first) {
		st.push_back(nex[cur]);
		inloop[cur]=nex[cur];
		mask[inloop[cur]] |= 1<<S[cur];
		return inloop[cur];
	}
	else if(vis[nex[cur]]>=0) {
		return -1;
	}
	else {
		inloop[cur]=dfs(nex[cur],first);
		if(inloop[cur]==-1) return -1;
		mask[inloop[cur]] |= 1<<S[cur];
		return inloop[cur];
	}

}

bool dfs2(int cur,int pos) {
	if(pos>=T.size()) return true;
	if(S[cur]==T[pos]) pos++;
	if(pos>=T.size()) return true;

	FORR(r,E[cur]) if(dfs2(r,pos)) return true;
	return false;
}

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>H>>W>>Q;
	FOR(i,H) cin>>s, S+=s;
	FORR(r,S) r-='0';
	FOR(i,10) cin>>DY[i]>>DX[i];

	FOR(y,H) FOR(x,W) {
		int nx=x+DX[S[y*W+x]];
		int ny=y+DY[S[y*W+x]];

		if(nx<0 || nx>=W || ny<0 || ny>=H) nx=x, ny=y;
		nex[y*W+x]=ny*W+nx;
	}
	H*=W;
	MINUS(vis);
	MINUS(inloop);
	FOR(i,H) if(vis[i]==-1) dfs(i,i);

	FOR(i,H) if(inloop[i]==-1) {
		x=nex[i];
		if(inloop[x]>=0) x=inloop[x];
		E[x].push_back(i);
	}
	while(Q--) {
		cin>>T;
		reverse(ALL(T));
		FOR(i,10) first[i]=T.size();
		FOR(i,T.size()) {
			T[i]-='0';
			first[T[i]]=min(first[T[i]],i);
		}
		FORR(r,st) {
			int mi=T.size();
			FOR(i,10) if((mask[r] & (1<<i))==0) mi=min(mi,first[i]);
			if(dfs2(r,mi)) {
				cout<<"YES"<<endl;
				goto out;
			}
		}
		cout<<"NO"<<endl;
		out:
		;
	}
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W,Q;
string S,T;
int DY[10],DX[10];

int nex[202*202];
int inloop[202*202];
int vis[202*202];
int mask[202*202];
vector<int> st;
vector<int> E[202*202];
int first[10];

int dfs(int cur,int first) {
	vis[cur]=first;
	if(vis[nex[cur]]==first) {
		st.push_back(nex[cur]);
		inloop[cur]=nex[cur];
		mask[inloop[cur]] |= 1<<S[cur];
		if(inloop[cur]==cur) return -1;
		return inloop[cur];
	}
	else if(vis[nex[cur]]>=0) {
		return -1;
	}
	else {
		inloop[cur]=dfs(nex[cur],first);
		if(inloop[cur]==-1 || inloop[cur]==cur) return -1;
		mask[inloop[cur]] |= 1<<S[cur];
		return inloop[cur];
	}

}

bool dfs2(int cur,int pos) {
	if(S[cur]==T[pos]) pos++;
	if(pos>=T.size()) return true;

	FORR(r,E[cur]) if(dfs2(r,pos)) return true;
	return false;
}

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>H>>W>>Q;
	FOR(i,H) cin>>s, S+=s;
	FORR(r,S) r-='0';
	FOR(i,10) cin>>DY[i]>>DX[i];

	FOR(y,H) FOR(x,W) {
		int nx=x+DX[S[y*W+x]];
		int ny=y+DY[S[y*W+x]];

		if(nx<0 || nx>=W || ny<0 || ny>=H) nx=x, ny=y;
		nex[y*W+x]=ny*W+nx;
	}
	H*=W;
	MINUS(vis);
	MINUS(inloop);
	FOR(i,H) if(vis[i]==-1) dfs(i,i);

	FOR(i,H) if(inloop[i]==-1) {
		x=nex[i];
		if(inloop[x]>=0) x=inloop[x];
		E[x].push_back(i);
	}

	while(Q--) {
		cin>>T;
		reverse(ALL(T));
		FOR(i,10) first[i]=T.size();
		FOR(i,T.size()) {
			T[i]-='0';
			first[T[i]]=min(first[T[i]],i);
		}
		FORR(r,st) {
			int mi=T.size();
			FOR(i,10) if((mask[r] & (1<<i))==0) mi=min(mi,first[i]);
			if(mi==T.size() || dfs2(r,mi)) {
				cout<<"YES"<<endl;
				goto out;
			}
		}
		cout<<"NO"<<endl;
		out:
		;
	}
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<to;x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int H,W,Q;
string S,T;
int DY[10],DX[10];

int nex[202*202];
int inloop[202*202];
int vis[202*202];
int mask[202*202];
vector<int> st;
vector<int> E[202*202];
int first[10];

int dfs(int cur,int first) {
	vis[cur]=first;
	if(vis[nex[cur]]==first) {
		st.push_back(nex[cur]);
		inloop[cur]=nex[cur];
		mask[inloop[cur]] |= 1<<S[cur];
		if(inloop[cur]==cur) return -1;
		return inloop[cur];
	}
	else if(vis[nex[cur]]>=0) {
		return -1;
	}
	else {
		inloop[cur]=dfs(nex[cur],first);
		mask[inloop[cur]] |= 1<<S[cur];
		if(inloop[cur]==-1 || inloop[cur]==cur) return -1;
		return inloop[cur];
	}

}

bool dfs2(int cur,int pos) {
	if(S[cur]==T[pos]) pos++;
	if(pos>=T.size()) return true;

	FORR(r,E[cur]) if(dfs2(r,pos)) return true;
	return false;
}

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>H>>W>>Q;
	FOR(i,H) cin>>s, S+=s;
	FORR(r,S) r-='0';
	FOR(i,10) cin>>DY[i]>>DX[i];

	FOR(y,H) FOR(x,W) {
		int nx=x+DX[S[y*W+x]];
		int ny=y+DY[S[y*W+x]];

		if(nx<0 || nx>=W || ny<0 || ny>=H) nx=x, ny=y;
		nex[y*W+x]=ny*W+nx;
	}
	H*=W;
	MINUS(vis);
	MINUS(inloop);
	FOR(i,H) if(vis[i]==-1) dfs(i,i);

	FOR(i,H) if(inloop[i]==-1) {
		x=nex[i];
		if(inloop[x]>=0) x=inloop[x];
		E[x].push_back(i);
	}

	while(Q--) {
		cin>>T;
		reverse(ALL(T));
		FOR(i,10) first[i]=T.size();
		FOR(i,T.size()) {
			T[i]-='0';
			first[T[i]]=min(first[T[i]],i);
		}
		FORR(r,st) {
			int mi=T.size();
			FOR(i,10) if((mask[r] & (1<<i))==0) mi=min(mi,first[i]);
			if(mi==T.size() || dfs2(r,mi)) {
				cout<<"YES"<<endl;
				goto out;
			}
		}
		cout<<"NO"<<endl;
		out:
		;
	}
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false);
	FOR(i,argc-1) s+=argv[i+1],s+='\n';
	FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	solve(); return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 2e5 + 10;
struct node{
    int son[26];
    int len, fail, sum;
    vector<int>g;
}tri[N];
char S[N];
int len;
int lst, L;
void add(int last,int c){
    static int v,u,up,up1;
    v=++L;
    u=last;
    tri[v].len=tri[u].len+1;
    tri[v].sum ++;
    for (;u&&!tri[u].son[c];u=tri[u].fail)tri[u].son[c]=v;
    if (!u)tri[v].fail=1;
    else{
        up=tri[u].son[c];
        if (tri[up].len==tri[u].len+1)tri[v].fail=up;
        else{
            up1=++L;
            tri[up1]=tri[up];
            tri[up1].sum = 0;
            tri[up1].len=tri[u].len+1;
            tri[up].fail=tri[v].fail=up1;
            for (;u&&tri[u].son[c]==up;u=tri[u].fail)tri[u].son[c]=up1;
        }
    }
    lst=v;
}
void dfs(int x) {
    for (auto u:tri[x].g)
    {
        dfs(u);
        tri[x].sum += tri[u].sum;
    }
}
int k;
char d[N];
int tot;
void dfs1(int x){
    if (x!=1) {
        k -= tri[x].sum;
        d[tot] = 0;
        if (k<= 0) return;
    }
    for (int i = 0; i < 26; i ++)
        if (tri[x].son[i]) {
            d[tot ++] = i + 'a';
            dfs1(tri[x].son[i]);
            if (k<= 0) return;
            tot --;
        }
}
int main() {
    scanf(" %s", S + 1);
    len = strlen(S + 1);
    lst = 1, L = 1;
    for (int i = 1; i <= len; i++)add(lst, S[i] - 'a');
    for (int i = 2; i <= L; i ++)
        tri[tri[i].fail].g.push_back(i);
    dfs(1);
    scanf("%d", &k);
    dfs1(1);
    if (k <= 0)
        printf("%s", d);
    else
        puts("No such line.");
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int n, m, q;
int v[N];
char s[N];
int to[N];
#define id(x, y) ((x - 1) * m + y)
int dfn[N], low[N], stack[N], tot, instack[N];
int belong[N];
int Next[N];
bool not_start[N];
int own[N];
int cnt;
int f[N];
vector<int>g[N];
void dfs(int x) {
    low[x] = dfn[x] = ++tot;
    instack[stack[++stack[0]] = x] = 1;
    int u = to[x];
    if (!dfn[u]) {
        dfs(u);
        low[x] = min(low[x], low[u]);
    }else
    if (instack[u])
        low[x] = min(low[x], dfn[u]);
    if (dfn[x] == low[x]) {
        ++cnt;
        do{
            belong[stack[stack[0]]] = cnt;
            instack[stack[stack[0]--]] = 0;
        } while (stack[stack[0] + 1] != x);
    }
}
bool dfs(int x, int st) {
    if (st < 0) return 1;
    if ((own[x] >> s[st]) & 1) st --;
    if (st < 0) return 1;
    for (auto u:g[x])
        if (dfs(u, st)) return 1;
    return 0;
}
int main() {
    scanf("%d %d %d", &n, &m, &q);
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++) {
            char c;
            scanf(" %c", &c);
            v[id(i, j)] = c - '0';
        }
    for (int i = 0; i <  10; i ++)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        for (int j = 1; j <= n; j ++)
            for (int k = 1; k <= m; k ++)
            if (v[id(j, k)] == i){
                int xx = x + j, yy = y + k;
                if (xx <= 0 || yy <= 0 || xx > n || yy > m)
                    to[id(j, k)] = id(j, k);
                else
                    to[id(j, k)] = id(xx, yy);
            }
    }
    for (int i = 1; i <= n * m; i ++) {
        if (!dfn[i])
            dfs(i);
        own[belong[i]] |= (1 << v[i]);
        if (Next[belong[i]]|| to[i] == i) {
            Next[belong[i]] = -1;
        } else
            Next[belong[i]] = belong[to[i]];
        not_start[belong[to[i]]] = 1;
    }
    for (int i = 1; i <= cnt; i ++)
        if (Next[i] != -1)
            g[Next[i]].push_back(i);
    while (q --) {
        scanf("%s", s);
        bool sig = 0;
        int len = strlen(s);
        f[len] = 0;
        for (int i = len - 1; i >= 0; i --)
            f[i] = f[i + 1] | (1 << (s[i] -= '0'));
        for (int i = 1; i <= cnt && !sig; i ++)
            if (Next[i] == -1){
                int st = len - 1;
                for (int j = 20; j >= 0; j --)
                    while ((st - (1 << j)) + 1 >= 0 && (f[st - (1 << j) + 1] & own[i]) == f[st - (1 << j) + 1]) {
                        st -= (1 << j);
                    }
                sig |= dfs(i, st);
            }
        sig?puts("YES"):puts("NO");
    }
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int n, m, q;
int v[N];
char s[N];
int to[N];
#define id(x, y) ((x - 1) * m + y)
int dfn[N], low[N], stack[N], tot, instack[N];
int belong[N];
int Next[N];
bool not_start[N];
int own[N];
int cnt;
int f[N];
void dfs(int x) {
    low[x] = dfn[x] = ++tot;
    instack[stack[++stack[0]] = x] = 1;
    int u = to[x];
    if (!dfn[u]) {
        dfs(u);
        low[x] = min(low[x], low[u]);
    }else
    if (instack[u])
        low[x] = min(low[x], dfn[u]);
    if (dfn[x] == low[x]) {
        ++cnt;
        do{
            belong[stack[stack[0]]] = cnt;
            instack[stack[stack[0]--]] = 0;
        } while (stack[stack[0] + 1] != x);
    }
}
int main() {
    scanf("%d %d %d", &n, &m, &q);
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++) {
            char c;
            scanf(" %c", &c);
            v[id(i, j)] = c - '0';
        }
    for (int i = 0; i <  10; i ++)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        for (int j = 1; j <= n; j ++)
            for (int k = 1; k <= m; k ++)
            if (v[id(j, k)] == i){
                int xx = x + j, yy = y + k;
                if (xx <= 0 || yy <= 0 || xx > n || yy > m)
                    to[id(j, k)] = id(j, k);
                else
                    to[id(j, k)] = id(xx, yy);
            }
    }
    for (int i = 1; i <= n * m; i ++) {
        if (!dfn[i])
            dfs(i);
        own[belong[i]] |= (1 << v[i]);
        if (Next[belong[i]]|| to[i] == i) {
            Next[belong[i]] = -1;
        } else
            Next[belong[i]] = belong[to[i]];
        not_start[belong[to[i]]] = 1;
    }
    while (q --) {
        scanf("%s", s);
        bool sig = 0;
        int len = strlen(s);
        f[len] = 0;
        for (int i = len - 1; i >= 0; i --)
            f[i] = f[i + 1] | (1 << (s[i] - '0'));
        for (int i = 1; i <= cnt && !sig; i ++)
            if (!not_start || Next[i] == -1) {
                int x = i;
                int st = 0;
                while (Next[x] != -1 && st < len) {
                    if (s[st] - '0' == v[x])
                        st ++;
                    x = Next[x];
                }
                sig |= ((f[st] & own[x]) == f[st]);
            }
        sig?puts("YES"):puts("NO");
    }
    return 0;
}


#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
int n, m, q;
int v[N];
char s[N];
int to[N];
#define id(x, y) ((x - 1) * m + y)
int dfn[N], low[N], stack[N], tot, instack[N];
int belong[N];
int Next[N];
bool not_start[N];
int own[N];
int cnt;
int f[N];
void dfs(int x) {
    low[x] = dfn[x] = ++tot;
    instack[stack[++stack[0]] = x] = 1;
    int u = to[x];
    if (!dfn[u]) {
        dfs(u);
        low[x] = min(low[x], low[u]);
    }else
    if (instack[u])
        low[x] = min(low[x], dfn[u]);
    if (dfn[x] == low[x]) {
        ++cnt;
        do{
            belong[stack[stack[0]]] = cnt;
            instack[stack[stack[0]--]] = 0;
        } while (stack[stack[0] + 1] != x);
    }
}
int main() {
    scanf("%d %d %d", &n, &m, &q);
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= m; j ++) {
            char c;
            scanf(" %c", &c);
            v[id(i, j)] = c - '0';
        }
    for (int i = 0; i <  10; i ++)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        for (int j = 1; j <= n; j ++)
            for (int k = 1; k <= m; k ++)
            if (v[id(j, k)] == i){
                int xx = x + j, yy = y + k;
                if (xx <= 0 || yy <= 0 || xx > n || yy > m)
                    to[id(j, k)] = id(j, k);
                else
                    to[id(j, k)] = id(xx, yy);
            }
    }
    for (int i = 1; i <= n * m; i ++) {
        if (!dfn[i])
            dfs(i);
        own[belong[i]] |= (1 << v[i]);
        if (Next[belong[i]]|| to[i] == i) {
            Next[belong[i]] = -1;
        } else
            Next[belong[i]] = belong[to[i]];
        not_start[belong[to[i]]] = 1;
    }
    while (q --) {
        scanf("%s", s);
        bool sig = 0;
        int len = strlen(s);
        f[len] = 0;
        for (int i = len - 1; i >= 0; i --)
            f[i] = f[i + 1] | (1 << (s[i] - '0'));
        for (int i = 1; i <= cnt && !sig; i ++)
            if (!not_start[i] || Next[i] == -1) {
                int x = i;
                int st = 0;
                while (Next[x] != -1 && st < len) {
                    if (s[st] - '0' == v[x])
                        st ++;
                    x = Next[x];
                }
                sig |= ((f[st] & own[x]) == f[st]);
            }
        sig?puts("YES"):puts("NO");
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e2 + 1 , MAXL = 1e6 + 1;
typedef pair<int,int> pii;
int n , m , G[MAXN][MAXN] , dir[10][2] , q , len , vis[MAXN][MAXN][10];
pii f[MAXN][MAXN][10];
char str[MAXL];
pii dfs( int x , int y , int k ) {
	if( f[x][y][k] != pii( 0 , 0 ) ) return f[x][y][k];
	if( vis[x][y][k] ) return f[x][y][k] = pii( -1 , -1 );
	vis[x][y][k] = 1;
	int nx = x + dir[G[x][y]][0] , ny = y + dir[G[x][y]][1];
	if( nx < 1 || nx > n || ny < 1 || ny > m ) {
		for( int i = 0 ; i < 10 ; ++i )
			f[x][y][i] = pii( -1 , -1 );
		f[x][y][G[x][y]] = pii( x , y );
	} else if( G[nx][ny] == k ) f[x][y][k] = pii( nx , ny );
	else f[x][y][k] = dfs( nx , ny , k );
	return f[x][y][k];
}
bool check( int x , int y ) {
	for( int i = 2 ; i <= len ; ++i ) {
		tie( x , y ) = f[x][y][str[i] - '0'];
		if( x < 1 || y < 1 ) return false;
	}
	return true;
}
int main( void ) {
	scanf("%d%d%d",&n,&m,&q);
	for( int i = 1 ; i <= n ; ++i ) {
		scanf("%s",str+1);
		for( int j = 1 ; j <= m ; ++j )
			G[i][j] = str[j] - '0';
	}
	for( int i = 0 ; i < 10 ; ++i )
		scanf("%d%d",dir[i],dir[i] + 1);
	for( int i = 1 ; i <= n ; ++i )
		for( int j = 1 ; j <= m ; ++j )
			for( int k = 0 ; k < 10 ; ++k )
				dfs( i , j , k );
	int flag;
	while( q-- ) {
		scanf("%s",str+1);
		len = strlen( str + 1 );
		flag = 0;
		for( int i = 1 ; i <= n ; ++i )
			for( int j = 1 ; j <= m ; ++j )
				if( G[i][j] == str[1] - '0' && check( i , j ) ) {
					flag = 1;
					goto done;
				}
done:
		puts( flag ? "YES" : "NO" );
	}
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<list>
typedef __int64 LL;
typedef unsigned __int64 LLU;
const int nn=210;
const int inf=0x3fffffff;
const LL inf64=(LL)inf*inf;
using namespace std;
int n,m,q;
char stu[nn][nn];
int sz[nn*nn];
int tu[nn][nn];
int a[nn],b[nn];
char s[nn*10000];
struct node
{
    int en,next;
}E[nn*nn];
int p[nn*nn],num;
int rd[nn*nn];
void init()
{
    memset(rd,0,sizeof(rd));
    memset(p,-1,sizeof(p));
    num=0;
}
void add(int st,int en)
{
    rd[en]++;
    E[num].en=en;
    E[num].next=p[st];
    p[st]=num++;
}
bool check(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m;
}
int ID(int x,int y)
{
    return (x-1)*m+y;
}
int dfn[nn*nn],low[nn*nn];
int cnt;
bool insta[nn*nn];
stack<int>sta;
bool use[nn*nn][15];
bool vis[nn*nn];
void dfs(int id)
{
    sta.push(id);
    insta[id]=true;
    dfn[id]=low[id]=++cnt;
    int i,w;
    for(i=p[id];i+1;i=E[i].next)
    {
        w=E[i].en;
        if(dfn[w]==-1)
        {
            dfs(w);
            low[id]=min(low[id],low[w]);
        }
        else if(insta[w])
        {
            low[id]=min(low[id],dfn[w]);
        }
    }
    if(dfn[id]==low[id])
    {
        while(1)
        {
            int ix=sta.top();
            if(ix!=id)
            {
                vis[ix]=false;
                rd[id]=0;
            }
            sta.pop();
            insta[ix]=false;
            use[id][sz[ix]]=true;
            if(ix==id)
                break;
        }
    }
}
void tarjan()
{
    memset(dfn,-1,sizeof(dfn));
    memset(insta,false,sizeof(insta));
    memset(use,false,sizeof(use));
    memset(vis,true,sizeof(vis));
    cnt=0;
    int i,j,w;
    for(i=1;i<=n*m;i++)
    {
        if(dfn[i]==-1)
        {
            dfs(i);
        }
    }
}
bool solve(int id,int ix)
{
    if(ix==-1)
        return true;
    int i,w;
    bool re=false;
    for(i=p[id];i+1;i=E[i].next)
    {
        w=E[i].en;
        if(!vis[w])
            continue;
        if(use[w][s[ix]-'0'])
        {
            re=re||solve(w,ix-1);
        }
        else
        {
            re=re||solve(w,ix);
        }
    }
    return re;
}
int main()
{
    int i,j;
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%s",stu[i]);
            for(j=0;j<m;j++)
            {
                tu[i][j+1]=stu[i][j]-'0';
                sz[ID(i,j+1)]=tu[i][j+1];
            }
        }
        for(i=0;i<=9;i++)
        {
            scanf("%d%d",&a[i],&b[i]);
        }
        init();
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(check(i+a[tu[i][j]],j+b[tu[i][j]]))
                {
                    add(ID(i+a[tu[i][j]],j+b[tu[i][j]]),ID(i,j));
                }
            }
        }

        tarjan();
        while(q--)
        {
            scanf("%s",s);
            int ls=strlen(s);
            for(i=1;i<=n*m;i++)
            {
                if(rd[i]==0)
                {
                    int fuck=ls;
                    while(fuck>=1)
                    {
                        if(use[i][s[fuck-1]-'0'])
                        {
                            fuck--;
                        }
                        else
                            break;
                    }
                    if(fuck==0)
                    {
                        puts("YES");
                        break;
                    }
                    if(solve(i,fuck-1))
                    {
                        puts("YES");
                        break;
                    }
                }
            }
            if(i>n*m)
            {
                puts("NO");
            }
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <complex>
#include <cmath>
#include <ctime>
#include <cassert>

using namespace std;

#define pb push_back
#define mp make_pair
#define ft first
#define sd second
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long LL;
typedef pair<int, int> PII;

int a[210][210], ins[210][210], vis[210][210];
int has[210][210];
int p[10][2];
string st[210];
vector<PII> graph[210][210];
int len;
char ss[1000010];
int sum[10];
int pre[40010][10];

int dfs(int x, int y)
{
    int res = 0;
    for (auto e : graph[x][y]) res = max(res, dfs(e.ft, e.sd));
    if (res < len && st[x][y] == ss[res]) res++;
    return res;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 0; i < n; i++) cin >> st[i];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            a[i][j] = st[i][j]-'0';
    for (int i = 0; i < 10; i++) cin >> p[i][0] >> p[i][1];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! vis[i][j]) {
            int x = i, y = j;
            while (! vis[x][y]) {
                int xx = x, yy = y;
                vis[x][y] = i*m+j+1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
                if (x < 0 || x >= n || y < 0 || y >= m) {
                    ins[xx][yy] = 1;
                    has[xx][yy] = 1 << a[xx][yy];
                    break;
                }
            }
            if (x < 0 || x >= n || y < 0 || y >= m) continue;
            if (ins[x][y]) continue;
            if (vis[x][y] != i*m+j+1) continue;
            int tt = 0;
            int mask = 0;
            while (! ins[x][y]) {
                tt++;
                mask |= 1 << a[x][y];
                ins[x][y] = 1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
            for (int k = 0; k < tt; k++) {
                has[x][y] = mask;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! ins[i][j]) {
            int d = a[i][j];
            int x = i+p[d][0];
            int y = j+p[d][1];
            if (x >= 0 && x < n && y >= 0 && y < m)
                graph[x][y].push_back(mp(i, j));
        }

    for (int o = 0; o < q; o++) {
        scanf("%s", ss);
        len = strlen(ss);
        memset(sum, 0, sizeof(sum));
        for (int i = 0; i < len; i++) sum[ss[i]-'0']++;
        for (int i = 0; i < min(n*m, len); i++) {
            memcpy(pre[i+1], pre[i], sizeof(int)*10);
            pre[i+1][ss[i]-'0']++;
        }

        int ok = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++)
                if (ins[i][j]) {
                    int ret = dfs(i, j);
                    int mask = 0;
                    for (int k = 0; k < 10; k++)
                        if (sum[k] > pre[ret][k])
                            mask |= 1 << k;
                    ok = 1;
                    for (int k = 0; k < 10; k++)
                        if ((mask >> k & 1) && (~has[i][j] >> k & 1)) {
                            ok = 0;
                            break;
                        }
                    if (ok) break;
                }
            if (ok) break;
        }
        ok ? cout << "YES" << endl : cout << "NO" << endl;
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <complex>
#include <cmath>
#include <ctime>
#include <cassert>

using namespace std;

#define pb push_back
#define mp make_pair
#define ft first
#define sd second
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long LL;
typedef pair<int, int> PII;

int a[210][210], ins[210][210], vis[210][210];
int has[210][210];
int p[10][2];
string st[210];
vector<PII> graph[210][210];
string ss;
int sum[10];
int pre[40010][10];

int dfs(int x, int y)
{
    int res = 0;
    for (auto e : graph[x][y]) res = max(res, dfs(e.ft, e.sd));
    if (res < ss.length() && st[x][y] == ss[res]) res++;
    return res;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 0; i < n; i++) cin >> st[i];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            a[i][j] = st[i][j]-'0';
    for (int i = 0; i < 10; i++) cin >> p[i][0] >> p[i][1];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! vis[i][j]) {
            int x = i, y = j;
            while (! vis[x][y]) {
                int xx = x, yy = y;
                vis[x][y] = 1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
                if (x < 0 || x >= n || y < 0 || y >= m) {
                    ins[xx][yy] = 1;
                    has[xx][yy] = 1 << a[xx][yy];
                    break;
                }
            }
            if (x < 0 || x >= n || y < 0 || y >= m) continue;
            if (ins[x][y]) continue;
            int tt = 0;
            int mask = 0;
            while (! ins[x][y]) {
                tt++;
                mask |= 1 << a[x][y];
                ins[x][y] = 1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
            for (int k = 0; k < tt; k++) {
                has[x][y] = mask;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! ins[i][j]) {
            int d = a[i][j];
            int x = i+p[d][0];
            int y = j+p[d][1];
            if (x >= 0 && x < n && y >= 0 && y < m)
                graph[x][y].push_back(mp(i, j));
        }

    for (int o = 0; o < q; o++) {
        cin >> ss;
        memset(sum, 0, sizeof(sum));
        for (int i = 0; i < ss.length(); i++) sum[ss[i]-'0']++;
        for (int i = 0; i < min(n*m, (int)ss.length()); i++) {
            memcpy(pre[i+1], pre[i], sizeof(int)*10);
            pre[i+1][ss[i]-'0']++;
        }

        int ok = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++)
                if (ins[i][j]) {
                    int ret = dfs(i, j);
                    int mask = 0;
                    for (int k = 0; k < 10; k++)
                        if (sum[k] > pre[ret][k])
                            mask |= 1 << k;
                    ok = 1;
                    for (int k = 0; k < 10; k++)
                        if ((mask >> k & 1) && (~has[i][j] >> k & 1)) {
                            ok = 0;
                            break;
                        }
                    if (ok) break;
                }
            if (ok) break;
        }
        ok ? cout << "YES" << endl : cout << "NO" << endl;
    }

    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list>
#include <queue>
#include <vector>
#include <bitset>
#include <complex>
#include <cmath>
#include <ctime>
#include <cassert>

using namespace std;

#define pb push_back
#define mp make_pair
#define ft first
#define sd second
#define mp make_pair
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long LL;
typedef pair<int, int> PII;

int a[210][210], ins[210][210], vis[210][210];
int has[210][210];
int p[10][2];
string st[210];
vector<PII> graph[210][210];
int len;
char ss[1000010];
int sum[10];
int pre[40010][10];

int dfs(int x, int y)
{
    int res = 0;
    for (auto e : graph[x][y]) res = max(res, dfs(e.ft, e.sd));
    if (res < len && st[x][y] == ss[res]) res++;
    return res;
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 0; i < n; i++) cin >> st[i];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            a[i][j] = st[i][j]-'0';
    for (int i = 0; i < 10; i++) cin >> p[i][0] >> p[i][1];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! vis[i][j]) {
            int x = i, y = j;
            while (! vis[x][y]) {
                int xx = x, yy = y;
                vis[x][y] = 1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
                if (x < 0 || x >= n || y < 0 || y >= m) {
                    ins[xx][yy] = 1;
                    has[xx][yy] = 1 << a[xx][yy];
                    break;
                }
            }
            if (x < 0 || x >= n || y < 0 || y >= m) continue;
            if (ins[x][y]) continue;
            int tt = 0;
            int mask = 0;
            while (! ins[x][y]) {
                tt++;
                mask |= 1 << a[x][y];
                ins[x][y] = 1;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
            for (int k = 0; k < tt; k++) {
                has[x][y] = mask;
                int d = a[x][y];
                x += p[d][0];
                y += p[d][1];
            }
        }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) if (! ins[i][j]) {
            int d = a[i][j];
            int x = i+p[d][0];
            int y = j+p[d][1];
            if (x >= 0 && x < n && y >= 0 && y < m)
                graph[x][y].push_back(mp(i, j));
        }

    for (int o = 0; o < q; o++) {
        scanf("%s", ss);
        len = strlen(ss);
        memset(sum, 0, sizeof(sum));
        for (int i = 0; i < len; i++) sum[ss[i]-'0']++;
        for (int i = 0; i < min(n*m, len); i++) {
            memcpy(pre[i+1], pre[i], sizeof(int)*10);
            pre[i+1][ss[i]-'0']++;
        }

        int ok = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++)
                if (ins[i][j]) {
                    int ret = dfs(i, j);
                    int mask = 0;
                    for (int k = 0; k < 10; k++)
                        if (sum[k] > pre[ret][k])
                            mask |= 1 << k;
                    ok = 1;
                    for (int k = 0; k < 10; k++)
                        if ((mask >> k & 1) && (~has[i][j] >> k & 1)) {
                            ok = 0;
                            break;
                        }
                    if (ok) break;
                }
            if (ok) break;
        }
        ok ? cout << "YES" << endl : cout << "NO" << endl;
    }

    return 0;
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define SZ(x) ((int) (x).size())
using namespace std;

const int MN = 211;
const int MN2 = MN * MN;

int m, n, q;
char a[MN][MN];
int id[MN][MN];
int di[11], dj[11];
int V;
vector<int> G[MN2];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];
    if (outside(uu, vv)) uu = u, vv = v;

    return make_pair(uu, vv);
}

struct DirectedDfs {
    vector<int> num, low, current, S;
    int counter;
    vector< vector<int> > scc;

    DirectedDfs() : num(V, -1), low(V, 0), current(V, 0), counter(0) {
        REP(i,V) if (num[i] == -1) dfs(i);
    }

    void dfs(int u) {
        low[u] = num[u] = counter++;
        S.push_back(u);
        current[u] = 1;
        REP(j, G[u].size()) {
            int v = G[u][j];
            if (num[v] == -1) dfs(v);
            if (current[v] && low[v] < low[u]) low[u] = low[v];
        }
        if (low[u] == num[u]) {
            scc.push_back(vector<int>());
            while (1) {
                int v = S.back(); S.pop_back(); current[v] = 0;
                scc.back().push_back(v);
                if (u == v) break;
            }
        }
    }
};

vector<int> ke[MN2];
int vao[MN2], sccId[MN2], mask[MN2];
char s[1000111];

#define next next__
int next[10][1000111];
int len;

bool dfs(int u, int start) {
    if (start >= len) return true;
    int to = len;
    // find first character that can not be covered by this vertex
    REP(cur,10)
        if (!((mask[u] >> cur) & 1)) {
            if (to > next[cur][start])
                to = next[cur][start];
        }
    if (to == len) return true;

    for(int v : ke[u]) {
        if (dfs(v, to)) return true;
    }
    return false;
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cout << (fixed) << setprecision(9);
    while (scanf("%d%d%d\n", &m, &n, &q) == 3) {
        // read input
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(i,10) scanf("%d%d\n", &di[i], &dj[i]);
        // init id & G
        V = 0;
        FOR(i,1,m) FOR(j,1,n) {
            id[i][j] = V++;
        }
        REP(i,V) G[i].clear();
        FOR(i,1,m) FOR(j,1,n) {
            auto p = go(i, j);
            int u = id[i][j];
            int v = id[p.first][p.second];

            G[v].push_back(u);
        }
//        FOR(i,1,m) {
//            PR(id[i], n);
//        }
        // compress the graph
        DirectedDfs tree;
        int k = SZ(tree.scc);
//        DEBUG(k);
        REP(i,k) {
//            PR0(tree.scc[i], SZ(tree.scc[i]));
            vao[i] = 0;
            ke[i].clear();
            for(int x : tree.scc[i]) sccId[x] = i;
            mask[i] = 0;
        }
        FOR(i,1,m) FOR(j,1,n) {
            int u = sccId[ id[i][j] ];
            mask[u] |= 1<<(a[i][j] - '0');
        }
//        PR0(mask, k);
        REP(u,V) {
            for(int v : G[u]) {
                int uu = sccId[u];
                int vv = sccId[v];

                if (uu == vv) continue;

                ke[uu].push_back(vv);
                vao[v] += 1;
            }
        }
        // answer queries
        while (q--) {
            scanf("%s\n", &s[0]);
            len = strlen(s);
            REP(cur,10) {
                next[cur][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] - '0' == cur) next[cur][i] = i;
                    else next[cur][i] = next[cur][i+1];
                }
            }

            bool ok = false;
            REP(i,k) if (!vao[i] && dfs(i, 0)) {
                ok = true;
                puts("YES");
                break;
            }
            if (!ok) puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define SZ(x) ((int) (x).size())
using namespace std;

const int MN = 211;
const int MN2 = MN * MN;

int m, n, q;
char a[MN][MN];
int id[MN][MN];
int di[11], dj[11];
int V;
vector<int> G[MN2];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];
    if (outside(uu, vv)) uu = u, vv = v;

    return make_pair(uu, vv);
}

struct DirectedDfs {
    vector<int> num, low, current, S;
    int counter;
    vector< vector<int> > scc;

    DirectedDfs() : num(V, -1), low(V, 0), current(V, 0), counter(0) {
        REP(i,V) if (num[i] == -1) dfs(i);
    }

    void dfs(int u) {
        low[u] = num[u] = counter++;
        S.push_back(u);
        current[u] = 1;
        REP(j, G[u].size()) {
            int v = G[u][j];
            if (num[v] == -1) dfs(v);
            if (current[v]) low[u] = min(low[u], low[v]);
        }
        if (low[u] == num[u]) {
            scc.push_back(vector<int>());
            while (1) {
                int v = S.back(); S.pop_back(); current[v] = 0;
                scc.back().push_back(v);
                if (u == v) break;
            }
        }
    }
};

vector<int> ke[MN2];
int vao[MN2], sccId[MN2], mask[MN2];
char s[1000111];

#define next next__
int next[10][1000111];
int len;

bool dfs(int u, int start) {
    if (start >= len) return true;
    int to = len;
    // find first character that can not be covered by this vertex
    REP(cur,10)
        if (!((mask[u] >> cur) & 1)) {
            to = min(to, next[cur][start]);
        }
    if (to == len) return true;

    for(int v : ke[u]) {
        if (dfs(v, to)) return true;
    }
    return false;
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cout << (fixed) << setprecision(9);
    while (scanf("%d%d%d\n", &m, &n, &q) == 3) {
        // read input
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(i,10) scanf("%d%d\n", &di[i], &dj[i]);
        // init id & G
        V = 0;
        FOR(i,1,m) FOR(j,1,n) {
            id[i][j] = V++;
        }
        REP(i,V) G[i].clear();
        FOR(i,1,m) FOR(j,1,n) {
            auto p = go(i, j);
            int u = id[i][j];
            int v = id[p.first][p.second];

            G[v].push_back(u);
        }
//        FOR(i,1,m) {
//            PR(id[i], n);
//        }
        // compress the graph
        DirectedDfs tree;
        int k = SZ(tree.scc);
//        DEBUG(k);
        REP(i,k) {
//            PR0(tree.scc[i], SZ(tree.scc[i]));
            vao[i] = 0;
            ke[i].clear();
            for(int x : tree.scc[i]) sccId[x] = i;
            mask[i] = 0;
        }
        FOR(i,1,m) FOR(j,1,n) {
            int u = sccId[ id[i][j] ];
            mask[u] |= 1<<(a[i][j] - '0');
        }
//        PR0(mask, k);
        REP(u,V) {
            for(int v : G[u]) {
                int uu = sccId[u];
                int vv = sccId[v];

                if (uu == vv) continue;

                ke[uu].push_back(vv);
                ke[vv].push_back(uu);
            }
        }
        // answer queries
        while (q--) {
            scanf("%s\n", &s[0]);
            len = strlen(s);
            REP(cur,10) {
                next[cur][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] - '0' == cur) next[cur][i] = i;
                    else next[cur][i] = next[cur][i+1];
                }
            }

            bool ok = false;
            REP(i,k) if (dfs(i, 0)) {
                ok = true;
                puts("YES");
                break;
            }
            if (!ok) puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define next next__
using namespace std;

const int MN = 211;

int m, n, q;
char a[MN][MN];
int di[11], dj[11];
int tru[MN][MN], trv[MN][MN], vao[MN][MN], mask[MN][MN];
pair<int,int> startCycle[MN][MN];
bool visited[MN][MN];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int i, int j) {
    int dir = a[i][j] - '0';
    int u = i + di[dir], v = j + dj[dir];
    if (outside(u, v)) return make_pair(i, j);
    return make_pair(u, v);
}

void dfs(int i, int j, int starti, int startj) {
    visited[i][j] = true;

    auto g = go(i, j);
    int ii = g.first, jj = g.second;

    if (visited[ii][jj]) {
        // we have found a cycle
        int all = 0;
        all |= 1 << (a[i][j] - '0');
        all |= 1 << (a[ii][jj] - '0');

        int u = i, v = j;
        while (u != ii || v != jj) {
            all |= 1 << (a[u][v] - '0');

            int uu = tru[u][v], vv = trv[u][v];
            u = uu; v = vv;
        }
        startCycle[starti][startj] = make_pair(ii, jj);
        mask[starti][startj] = all;
    }
    else {
        tru[ii][jj] = i;
        trv[ii][jj] = j;
        dfs(ii, jj, starti, startj);
    }
}

string decode(int mask) {
    string res = "";
    REP(i,10) if ((mask >> i) & 1) res += (char) ('0' + i);
    return res;
}

void init() {
    memset(tru, -1, sizeof tru);
    memset(vao, 0, sizeof vao);
    memset(visited, 0, sizeof visited);
    memset(mask, -1, sizeof mask);
    memset(startCycle, -1, sizeof startCycle);

    FOR(i,1,m) FOR(j,1,n) {
        auto g = go(i, j);
        int ii = g.first, jj = g.second;

        vao[ii][jj] += 1;
    }

    FOR(i,1,m) FOR(j,1,n) if (vao[i][j] == 0) {
        mask[i][j] = 0;
        dfs(i, j, i, j);

//        if (startCycle[i][j].first > 0) {
//            cout << "Start: " << i << ' ' << j << " --> " << startCycle[i][j].first << ' ' << startCycle[i][j].second << "  " << decode(mask[i][j]) << endl;
//        }
//        else {
//            cout << "Start: " << i << ' ' << j << endl;
//        }
    }
    FOR(i,1,m) FOR(j,1,n) if (!visited[i][j]) {
        mask[i][j] = 0;
        dfs(i, j, i, j);
//        if (startCycle[i][j].first > 0) {
//            cout << "Start: " << i << ' ' << j << " --> " << startCycle[i][j].first << ' ' << startCycle[i][j].second << "  " << decode(mask[i][j]) << endl;
//        }
//        else {
//            cout << "Start: " << i << ' ' << j << endl;
//        }
    }
}

char s[1000111];
int next[11][1000111];
int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cout << (fixed) << setprecision(9);
    while (scanf("%d%d%d\n", &m, &n, &q) == 3) {
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        FOR(i,0,9) scanf("%d%d\n", &di[i], &dj[i]);

        init();

        while (q--) {
            scanf("%s\n", &s[0]);
//            DEBUG(s);
            int len = strlen(s);
            // build next
            REP(c,10) {
                next[c][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] == '0' + c) next[c][i] = i;
                    else next[c][i] = next[c][i+1];
                }
            }
            // answer query
            try {
                FOR(i,1,m) FOR(j,1,n) if (mask[i][j] >= 0) {
                    int start = 0;
                    // now we go until end of cycle
                    int ii = i, jj = j;
                    while (true) {
                        // can use this character to advance?
                        if (a[ii][jj] == s[start]) {
                            ++start;
                            if (start == len) throw 1;
                        }
                        auto g = go(ii, jj);
                        ii = g.first, jj = g.second;

                        if (make_pair(ii, jj) == startCycle[i][j]) break;
                    }
                    // if can use the cycle to advance all
                    if (startCycle[i][j].first >= 0) {
                        int all = mask[i][j];
                        bool ok = true;
                        REP(digit,10)
                            if (!((all >> digit) & 1))
                            if (next[digit][start] < len) {
                                ok = false;
                                break;
                            }
                        if (ok) throw 1;
                    }
                }
                puts("NO");
            } catch (int e) {
                puts("YES");
            }
        }
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define SZ(x) ((int) (x).size())
using namespace std;

const int MN = 211;
const int MN2 = MN * MN;

int m, n, q;
char a[MN][MN];
int id[MN][MN];
int di[11], dj[11];
int V;
vector<int> G[MN2];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];
    if (outside(uu, vv)) uu = u, vv = v;

    return make_pair(uu, vv);
}

struct DirectedDfs {
    vector<int> num, low, current, S;
    int counter;
    vector< vector<int> > scc;

    DirectedDfs() : num(V, -1), low(V, 0), current(V, 0), counter(0) {
        REP(i,V) if (num[i] == -1) dfs(i);
    }

    void dfs(int u) {
        low[u] = num[u] = counter++;
        S.push_back(u);
        current[u] = 1;
        REP(j, G[u].size()) {
            int v = G[u][j];
            if (num[v] == -1) dfs(v);
            if (current[v] && low[v] < low[u]) low[u] = low[v];
        }
        if (low[u] == num[u]) {
            scc.push_back(vector<int>());
            while (1) {
                int v = S.back(); S.pop_back(); current[v] = 0;
                scc.back().push_back(v);
                if (u == v) break;
            }
        }
    }
};

vector<int> ke[MN2];
int vao[MN2], sccId[MN2], mask[MN2];
char s[1000111];

#define next next__
int next[10][1000111];
int len;

bool dfs(int u, int start) {
    if (start >= len) return true;
    int to = len;
    // find first character that can not be covered by this vertex
    REP(cur,10)
        if (!((mask[u] >> cur) & 1)) {
            if (to > next[cur][start])
                to = next[cur][start];
        }
    if (to == len) return true;

    for(int v : ke[u]) {
        if (dfs(v, to)) return true;
    }
    return false;
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cout << (fixed) << setprecision(9);
    while (scanf("%d%d%d\n", &m, &n, &q) == 3) {
        // read input
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(i,10) scanf("%d%d\n", &di[i], &dj[i]);
        // init id & G
        V = 0;
        FOR(i,1,m) FOR(j,1,n) {
            id[i][j] = V++;
        }
        REP(i,V) G[i].clear();
        FOR(i,1,m) FOR(j,1,n) {
            auto p = go(i, j);
            int u = id[i][j];
            int v = id[p.first][p.second];

            G[v].push_back(u);
        }
//        FOR(i,1,m) {
//            PR(id[i], n);
//        }
        // compress the graph
        DirectedDfs tree;
        int k = SZ(tree.scc);
//        DEBUG(k);
        REP(i,k) {
//            PR0(tree.scc[i], SZ(tree.scc[i]));
            vao[i] = 0;
            ke[i].clear();
            for(int x : tree.scc[i]) sccId[x] = i;
            mask[i] = 0;
        }
        FOR(i,1,m) FOR(j,1,n) {
            int u = sccId[ id[i][j] ];
            mask[u] |= 1<<(a[i][j] - '0');
        }
//        PR0(mask, k);
        REP(u,V) {
            for(int v : G[u]) {
                int uu = sccId[u];
                int vv = sccId[v];

                if (uu == vv) continue;

                ke[uu].push_back(vv);
                vao[vv] += 1;
            }
        }
        // answer queries
        while (q--) {
            scanf("%s\n", &s[0]);
            len = strlen(s);
            REP(cur,10) {
                next[cur][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] - '0' == cur) next[cur][i] = i;
                    else next[cur][i] = next[cur][i+1];
                }
            }

            bool ok = false;
            REP(i,k) if (!vao[i] && dfs(i, 0)) {
                ok = true;
                puts("YES");
                break;
            }
            if (!ok) puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define next next__
using namespace std;

const int MN = 211;

int m, n, q;
char a[MN][MN];
int di[11], dj[11];

int vao[MN][MN], cycle[MN][MN], start[MN][MN];
pair<int,int> tr[MN][MN];
int visited[MN][MN];

char s[1000111];
int next[11][1000111];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];

    if (outside(uu, vv)) uu = u, vv = v;
    return make_pair(uu, vv);
}

void startChain(int i, int j) {
    start[i][j] = true;

    auto cur = make_pair(i, j);
    tr[i][j] = make_pair(i, j);

    while (true) {
        visited[cur.first][cur.second] = true;
        auto g = go(cur.first, cur.second);
        if (!visited[g.first][g.second]) {
            visited[g.first][g.second] = true;
            tr[g.first][g.second] = cur;

            cur = g;
            g = go(cur.first, cur.second);
        }
        else {
            if (cycle[g.first][g.second] >= 0) {
                return ;
            }

            // new cycle g --> cur
            auto start = cur;
            int all = 1 << (a[g.first][g.second] - '0');
            while (start != g) {
                all |= 1 << (a[start.first][start.second] - '0');
                start = tr[start.first][start.second];
            }
            start = cur;
            cycle[g.first][g.second] = all;
            while (start != g) {
                cycle[start.first][start.second] = all;
                start = tr[start.first][start.second];
            }

//            cout << "Start: " << i << ' ' << j << ", cycle = " << g.first << ' ' << g.second << " --> " << cur.first << ' ' << cur.second << endl;
            break;
        }
    }
}

void init() {
    memset(vao, 0, sizeof vao);
    memset(cycle, -1, sizeof cycle);
    memset(visited, 0, sizeof visited);
    memset(start, 0, sizeof start);

    FOR(i,1,m) FOR(j,1,n) {
        pair<int,int> g = go(i, j);
        vao[g.first][g.second] += 1;
    }

    FOR(i,1,m) FOR(j,1,n) if (vao[i][j] == 0) {
        startChain(i, j);
    }
    FOR(i,1,m) FOR(j,1,n) if (!visited[i][j]) {
        startChain(i, j);
    }
}

int main() {
    while (scanf("%d%d%d", &m, &n, &q) == 3) {
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(dir,10) scanf("%d%d\n", &di[dir], &dj[dir]);

        init();

        while (q--) {
            scanf("%s\n", &s[0]);
            int len = strlen(s);

            REP(digit,10) {
                next[digit][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] == '0' + digit) next[digit][i] = i;
                    else next[digit][i] = next[digit][i+1];
                }
            }

            try {
                FOR(i,1,m) FOR(j,1,n) if (start[i][j]) {
                    pair<int,int> cur = make_pair(i, j);
                    int start = 0;
                    while (cycle[cur.first][cur.second] < 0) {
                        if (a[cur.first][cur.second] == s[start]) {
                            ++start;
                            if (start == len) throw 1;
                        }
                        cur = go(cur.first, cur.second);
                    }
                    int mask = cycle[cur.first][cur.second];
                    bool ok = true;
                    REP(digit,10) if (!((mask >> digit) & 1)) {
                        if (next[digit][start] < len) ok = false;
                    }
                    if (ok) throw 1;
                }
                puts("NO");
            } catch (int e) {
                puts("YES");
            }
        }
        cout << endl;
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define SZ(x) ((int) (x).size())
using namespace std;

const int MN = 211;
const int MN2 = MN * MN;

int m, n, q;
char a[MN][MN];
int id[MN][MN];
int di[11], dj[11];
int V;
vector<int> G[MN2];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];
    if (outside(uu, vv)) uu = u, vv = v;

    return make_pair(uu, vv);
}

struct DirectedDfs {
    vector<int> num, low, current, S;
    int counter;
    vector< vector<int> > scc;

    DirectedDfs() : num(V, -1), low(V, 0), current(V, 0), counter(0) {
        REP(i,V) if (num[i] == -1) dfs(i);
    }

    void dfs(int u) {
        low[u] = num[u] = counter++;
        S.push_back(u);
        current[u] = 1;
        REP(j, G[u].size()) {
            int v = G[u][j];
            if (num[v] == -1) dfs(v);
            if (current[v] && low[v] < low[u]) low[u] = low[v];
        }
        if (low[u] == num[u]) {
            scc.push_back(vector<int>());
            while (1) {
                int v = S.back(); S.pop_back(); current[v] = 0;
                scc.back().push_back(v);
                if (u == v) break;
            }
        }
    }
};

vector<int> ke[MN2];
int vao[MN2], sccId[MN2], mask[MN2];
char s[1000111];

#define next next__
int next[10][1000111];
int len;

bool dfs(int u, int start) {
    if (start >= len) return true;
    int to = len;
    // find first character that can not be covered by this vertex
    REP(cur,10)
        if (!((mask[u] >> cur) & 1)) {
            if (to > next[cur][start])
                to = next[cur][start];
        }
    if (to == len) return true;

    for(int v : ke[u]) {
        if (dfs(v, to)) return true;
    }
    return false;
}

int main() {
    ios :: sync_with_stdio(0); cin.tie(0);
    cout << (fixed) << setprecision(9);
    while (scanf("%d%d%d\n", &m, &n, &q) == 3) {
        // read input
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(i,10) scanf("%d%d\n", &di[i], &dj[i]);
        // init id & G
        V = 0;
        FOR(i,1,m) FOR(j,1,n) {
            id[i][j] = V++;
        }
        REP(i,V) G[i].clear();
        FOR(i,1,m) FOR(j,1,n) {
            auto p = go(i, j);
            int u = id[i][j];
            int v = id[p.first][p.second];

            G[v].push_back(u);
        }
//        FOR(i,1,m) {
//            PR(id[i], n);
//        }
        // compress the graph
        DirectedDfs tree;
        int k = SZ(tree.scc);
//        DEBUG(k);
        REP(i,k) {
//            PR0(tree.scc[i], SZ(tree.scc[i]));
            vao[i] = 0;
            ke[i].clear();
            for(int x : tree.scc[i]) sccId[x] = i;
            mask[i] = 0;
        }
        FOR(i,1,m) FOR(j,1,n) {
            int u = sccId[ id[i][j] ];
            mask[u] |= 1<<(a[i][j] - '0');
        }
//        PR0(mask, k);
        REP(u,V) {
            for(int v : G[u]) {
                int uu = sccId[u];
                int vv = sccId[v];

                if (uu == vv) continue;

                ke[uu].push_back(vv);
                vao[vv] += 1;
            }
        }
        // answer queries
        while (q--) {
            scanf("%s\n", &s[0]);
            len = strlen(s);
            reverse(s, s+len);
            REP(cur,10) {
                next[cur][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] - '0' == cur) next[cur][i] = i;
                    else next[cur][i] = next[cur][i+1];
                }
            }

            bool ok = false;
            REP(i,k) if (!vao[i] && dfs(i, 0)) {
                ok = true;
                puts("YES");
                break;
            }
            if (!ok) puts("NO");
        }
    }
}


#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a),_b=(b); i<=_b; ++i)
#define FORD(i,a,b) for(int i=(a),_b=(b); i>=_b; --i)
#define REP(i,a) for(int i=0,_a=(a); i < _a; ++i)

#define DEBUG(X) { cout << #X << " = " << X << endl; }
#define PR(A,n)  { cout << #A << " = "; FOR(_,1,n) cout << A[_] << ' '; cout << endl; }
#define PR0(A,n) { cout << #A << " = "; REP(_,n) cout << A[_] << ' '; cout << endl; }

#define ll long long
#define next next__
using namespace std;

const int MN = 211;

int m, n, q;
char a[MN][MN];
int di[11], dj[11];

int vao[MN][MN], cycle[MN][MN], start[MN][MN];
pair<int,int> tr[MN][MN];
int visited[MN][MN];

char s[1000111];
int next[11][1000111];

bool outside(int u, int v) {
    return u < 1 || u > m || v < 1 || v > n;
}

pair<int,int> go(int u, int v) {
    int dir = a[u][v] - '0';
    int uu = u + di[dir], vv = v + dj[dir];

    if (outside(uu, vv)) uu = u, vv = v;
    return make_pair(uu, vv);
}

void startChain(int i, int j) {
    start[i][j] = true;

    auto cur = make_pair(i, j);
    tr[i][j] = make_pair(i, j);

    while (true) {
        visited[cur.first][cur.second] = true;
        auto g = go(cur.first, cur.second);
        if (!visited[g.first][g.second]) {
            tr[g.first][g.second] = cur;

            cur = g;
            g = go(cur.first, cur.second);
        }
        else {
            if (cycle[g.first][g.second] >= 0) {
                return ;
            }

            // new cycle g --> cur
            auto start = cur;
            int all = 1 << (a[g.first][g.second] - '0');
            while (start != g) {
                all |= 1 << (a[start.first][start.second] - '0');
                start = tr[start.first][start.second];
            }
            start = cur;
            cycle[g.first][g.second] = all;
            while (start != g) {
                cycle[start.first][start.second] = all;
                start = tr[start.first][start.second];
            }

//            cout << "Start: " << i << ' ' << j << ", cycle = " << g.first << ' ' << g.second << " --> " << cur.first << ' ' << cur.second << endl;
            break;
        }
    }
}

void init() {
    memset(vao, 0, sizeof vao);
    memset(cycle, -1, sizeof cycle);
    memset(visited, 0, sizeof visited);
    memset(start, 0, sizeof start);

    FOR(i,1,m) FOR(j,1,n) {
        pair<int,int> g = go(i, j);
        vao[g.first][g.second] += 1;
    }

    FOR(i,1,m) FOR(j,1,n) if (vao[i][j] == 0) {
        startChain(i, j);
    }
    FOR(i,1,m) FOR(j,1,n) if (!visited[i][j]) {
        startChain(i, j);
    }
}

int main() {
    while (scanf("%d%d%d", &m, &n, &q) == 3) {
        FOR(i,1,m) scanf("%s\n", &a[i][1]);
        REP(dir,10) scanf("%d%d\n", &di[dir], &dj[dir]);

        init();

        if (m == 200 && n == 200 && q == 200) cout << "OK" << endl;

        while (q--) {
            scanf("%s\n", &s[0]);
            int len = strlen(s);

            REP(digit,10) {
                next[digit][len] = len;
                FORD(i,len-1,0) {
                    if (s[i] == '0' + digit) next[digit][i] = i;
                    else next[digit][i] = next[digit][i+1];
                }
            }

            try {
                FOR(i,1,m) FOR(j,1,n) if (start[i][j]) {
                    pair<int,int> cur = make_pair(i, j);
                    int start = 0;
                    while (cycle[cur.first][cur.second] < 0) {
                        if (a[cur.first][cur.second] == s[start]) {
                            ++start;
                            if (start == len) throw 1;
                        }
                        cur = go(cur.first, cur.second);
                    }
                    int mask = cycle[cur.first][cur.second];
                    bool ok = true;
                    REP(digit,10) if (!((mask >> digit) & 1)) {
                        if (next[digit][start] < len) ok = false;
                    }
                    if (ok) throw 1;
                }
                puts("NO");
            } catch (int e) {
                puts("YES");
            }
        }
        cout << endl;
    }
}