#include<bits/stdc++.h>
using namespace std;
int n,m,q,di[100],dj[100];
struct cell{
    string s;
    int cycle;
    cell(){cycle=0;s="";}
}cel;
vector<cell>v;
int a[205][205];
bool vis[205][205];
int x,y,add;
bool check(int i,int j)
{
    return i>=0&&i<n&&j>=0&&j<m;
}
void solve(int i,int j)
{
    vis[i][j]=1;
    int b=a[i][j];
    int ni=i+di[b],nj=j+dj[b];
    if(!check(ni,nj))
    {
        add=1;
        cel.cycle|=(1<<b);
        return;
    }
    if(vis[ni][nj])
    {
        x=ni;
        y=nj;
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
        return;
    }
    solve(ni,nj);
    if(add==0){
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
    }
    else cel.s+=char(b+'0');
    return;
}
    char query[1<<20];
int nums[10],remain,rem,num[10];
bool ok(cell&c)
{
    int j=0,b;
    for(int i=0;i<c.s.size();++i)
    {
        if((remain|c.cycle)==c.cycle)return 1;
        if(c.s[i]==query[j])
        {
            b=query[j]-'0';
            --nums[b];
            if(nums[b]==0)remain^=(1<<b);
        }

    }
    if((remain|c.cycle)==c.cycle)return 1;
    return 0;
}
int main()
{
    memset(vis,0,sizeof vis);
    cin>>n>>m>>q;
    char c;
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
        {
            cin>>c;
            a[i][j]=c-'0';
        }
    }
    for(int i=0;i<10;++i)cin>>di[i]>>dj[i];
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(!vis[i][j])
        {
            cel=cell();
            x=y=-1;
            add=0;
            solve(i,j);
            reverse(cel.s.begin(),cel.s.end());
            v.push_back(cel);
            /*cout<<i<<" "<<j<<endl;
            cout<<cel.s<<" "<<cel.cycle<<endl;
            cout<<endl;*/
        }
    }
    bool yes;
    for(int k=0;k<q;++k)
    {
        scanf("%s",query);
        for(int i=0;i<10;++i)num[i]=0;
        rem=0;
        for(int j=0;query[j]!='\0';++j)++num[query[j]-'0'];
        for(int i=0;i<10;++i)if(num[i])rem|=(1<<i);
        yes=0;
        for(int j=0;j<v.size();++j)
        {
            remain=rem;
            for(int i=0;i<10;++i)nums[i]=num[i];
            if(ok(v[j]))
            {
                yes=1;
                break;
            }
        }
        if(yes)cout<<"YES\n";
        else cout<<"NO\n";
    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q,di[100],dj[100];
struct cell{
    string s;
    int cycle;
    cell(){cycle=0;s="";}
}cel;
vector<cell>v;
int a[205][205];
bool vis[205][205],vis1[205][205],vis2[205][205];
int x,y,add;
bool check(int i,int j)
{
    return i>=0&&i<n&&j>=0&&j<m;
}
void solve(int i,int j)
{
    vis[i][j]=vis2[i][j]=1;
    int b=a[i][j];
    int ni=i+di[b],nj=j+dj[b];
    if(!check(ni,nj))
    {
        add=1;
        cel.cycle|=(1<<b);
        vis[i][j]=0;
        return;
    }
    if(vis[ni][nj])
    {
        x=ni;
        y=nj;
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
        vis[i][j]=0;
        return;
    }
    solve(ni,nj);
    if(add==0){
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
    }
    else cel.s+=char(b+'0');
    vis[i][j]=0;
    return;
}
    char query[1<<20];
int nums[10],remain,rem,num[10];
bool ok(cell&c)
{
    int j=0,b;
    for(int i=0;i<c.s.size();++i)
    {
        if((remain|c.cycle)==c.cycle)return 1;
        if(c.s[i]==query[j])
        {
            b=query[j]-'0';
            --nums[b];
            if(nums[b]==0)remain^=(1<<b);
        }

    }
    if((remain|c.cycle)==c.cycle)return 1;
    return 0;
}
int main()
{
    memset(vis,0,sizeof vis);
    memset(vis1,0,sizeof vis1);
    memset(vis2,0,sizeof vis2);
    cin>>n>>m>>q;
    char c;
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
        {
            cin>>c;
            a[i][j]=c-'0';
        }
    }
    for(int i=0;i<10;++i)cin>>di[i]>>dj[i];
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
    {
        int b=a[i][j];
        int ni=i+di[b],nj=j+dj[b];
        if(check(ni,nj)&&(ni!=i||nj!=j))vis1[ni][nj]=1;
    }
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(!vis1[i][j])
        {
            cel=cell();
            x=y=-1;
            add=0;
            solve(i,j);
            reverse(cel.s.begin(),cel.s.end());
            v.push_back(cel);
            /* cout<<i<<" "<<j<<endl;
            cout<<cel.s<<" "<<cel.cycle<<endl;
            cout<<endl;*/
        }
    }
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(!vis2[i][j])
        {
            cel=cell();
            x=y=-1;
            add=0;
            solve(i,j);
            reverse(cel.s.begin(),cel.s.end());
            v.push_back(cel);
           /* cout<<i<<" "<<j<<endl;
            cout<<cel.s<<" "<<cel.cycle<<endl;
            cout<<endl;*/
        }
    }
    bool yes;
    for(int k=0;k<q;++k)
    {
        scanf("%s",query);
        for(int i=0;i<10;++i)num[i]=0;
        rem=0;
        for(int j=0;query[j]!='\0';++j)++num[query[j]-'0'];
        for(int i=0;i<10;++i)if(num[i])rem|=(1<<i);
        yes=0;
        for(int j=0;j<v.size();++j)
        {
            remain=rem;
            for(int i=0;i<10;++i)nums[i]=num[i];
            if(ok(v[j]))
            {
                yes=1;
                break;
            }
        }
        if(yes)cout<<"YES\n";
        else cout<<"NO\n";
    }
}


#include<bits/stdc++.h>
using namespace std;
int n,m,q,di[100],dj[100];
struct cell{
    string s;
    int cycle;
    cell(){cycle=0;s="";}
}cel;
vector<cell>v;
int a[205][205];
bool vis[205][205],vis1[205][205],vis2[205][205];
int x,y,add;
bool check(int i,int j)
{
    return i>=0&&i<n&&j>=0&&j<m;
}
void solve(int i,int j)
{
    vis[i][j]=vis2[i][j]=1;
    int b=a[i][j];
    int ni=i+di[b],nj=j+dj[b];
    if(!check(ni,nj))
    {
        add=1;
        cel.cycle|=(1<<b);
        vis[i][j]=0;
        return;
    }
    if(vis[ni][nj])
    {
        x=ni;
        y=nj;
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
        vis[i][j]=0;
        return;
    }
    solve(ni,nj);
    if(add==0){
        cel.cycle|=(1<<b);
        if(i==ni&&j==nj)add=1;
    }
    else cel.s+=char(b+'0');
    vis[i][j]=0;
    return;
}
    char query[1<<20];
int nums[10],remain,rem,num[10];
bool ok(cell&c)
{
    int j=0,b;
    for(int i=0;i<c.s.size();++i)
    {
        if((remain|c.cycle)==c.cycle)return 1;
        if(c.s[i]==query[j])
        {
            b=query[j]-'0';
            --nums[b];
            if(nums[b]==0)remain^=(1<<b);
        }

    }
    if((remain|c.cycle)==c.cycle)return 1;
    return 0;
}
int main()
{
    memset(vis,0,sizeof vis);
    memset(vis1,0,sizeof vis1);
    cin>>n>>m>>q;
    char c;
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
        {
            cin>>c;
            a[i][j]=c-'0';
        }
    }
    for(int i=0;i<10;++i)cin>>di[i]>>dj[i];
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
    {
        int b=a[i][j];
        int ni=i+di[b],nj=j+dj[b];
        if(check(ni,nj)&&(ni!=i||nj!=j))vis1[ni][nj]=1;
    }
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(!vis1[i][j])
        {
            cel=cell();
            x=y=-1;
            add=0;
            solve(i,j);
            reverse(cel.s.begin(),cel.s.end());
            v.push_back(cel);
            /* cout<<i<<" "<<j<<endl;
            cout<<cel.s<<" "<<cel.cycle<<endl;
            cout<<endl;*/
        }
    }
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<m;++j)
            if(!vis2[i][j])
        {
            cel=cell();
            x=y=-1;
            add=0;
            solve(i,j);
            reverse(cel.s.begin(),cel.s.end());
            v.push_back(cel);
           /* cout<<i<<" "<<j<<endl;
            cout<<cel.s<<" "<<cel.cycle<<endl;
            cout<<endl;*/
        }
    }
    bool yes;
    for(int k=0;k<q;++k)
    {
        scanf("%s",query);
        if(n==200&&m==200&&k==0)cout<<query<<endl;

        for(int i=0;i<10;++i)num[i]=0;
        rem=0;
        for(int j=0;query[j]!='\0';++j)++num[query[j]-'0'];
        for(int i=0;i<10;++i)if(num[i])rem|=(1<<i);
        yes=0;
        for(int j=0;j<v.size();++j)
        {
            remain=rem;
            for(int i=0;i<10;++i)nums[i]=num[i];
            if(ok(v[j]))
            {
                yes=1;
                break;
            }
        }
        if(yes)cout<<"YES\n";
        else cout<<"NO\n";
    }
}


#include <bits/stdc++.h>
#ifndef M_PI
#define M_PI 3.14159265359
#endif // M_PI
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define GET(a, n) for (int __i = 0; __i < (n); ++__i) cin >> a[__i];
#define GETM(a, n, m) for (int __i = 0; __i < (n); ++__i) for (int __j = 0; __j < m; ++__j) cin >> a[__i][__j];
#define PRINTM(a, n, m) for (int __i = 0; __i < (n); ++__i) { for (int __j = 0; __j < m; ++__j) cout << a[__i][__j] << " ";  cout << endl; };
#define PRINT(a, n) for (int __i = 0; __i < (n); ++__i) cout << a[__i] << " ";
#define IT(a) a.begin(), a.end()
#define SQR(x) (x) * (x)
#define CASE(a, s) cout << "Case #" << a << ": " << s << endl;
#define DEB(a) cout << #a << " = " << (a) << endl; cout.flush();
#define DEBA(a) for (auto __i: a) cout << __i << " "; cout << endl; cout.flush();
#define IFDEB(b, a) if (b) { cout << #a << " = " << (a) << endl; cout.flush(); }
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
const int MOD = 1000000007;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <vector <PII>>> g;
string s;
vector <string> v;

int dfs(int x, int y, int pos) {
    if (pos + (v[x][y] == s[pos]) == s.size()) {
        return 1;
    }
    for (auto i: g[x][y]) {
        if (dfs(i.first, i.second, pos + (v[x][y] == s[pos]))) {
            return 1;
        }
    }
    return 0;
}

int main()
{
    int n, m, q;
    cin >> n >> m >> q;
    v.resize(n);
    GET(v, n);
    vector <int> dx(10);
    vector <int> dy(10);
    FOR (i, 0, 10) {
        cin >> dx[i] >> dy[i];
    }
    vector <vector <int>> used(n, vector <int> (m));
    vector <vector <int>> numbers(n, vector <int> (m));
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            if (used[i][j]) {
                continue;
            }
            int x = i;
            int y = j;
            vector <PII> num;
            while (!used[x][y]) {
                num.push_back({x, y});
                used[x][y] = 1;
                int x1 = x + dx[v[x][y] - '0'];
                int y1 = y + dy[v[x][y] - '0'];
                if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m) {
                    x = x1;
                    y = y1;
                }
            }
            if (used[x][y] == 2) {
                for (auto i: num) {
                    used[i.first][i.second] = 2;
                }
                continue;
            }
            reverse(IT(num));
            while (num.back() != make_pair(x, y)) {
                used[num.back().first][num.back().second] = 2;
                num.pop_back();
            }
            int mask = 0;
            for (auto l: num) {
                mask |= 1 << (v[l.first][l.second] - '0');
                v[l.first][l.second] = 'a';
            }
            for (auto l: num) {
                numbers[l.first][l.second] = mask;
                used[l.first][l.second] = 2;
            }
        }
    }
    g.resize(n);
    FOR (i, 0, n) {
        g[i].resize(m);
    }
    vector <vector <int>> indeg(n, vector <int> (m));
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            if (v[i][j] == 'a') {
                continue;
            }
            int x = i;
            int y = j;
            int x1 = x + dx[v[x][y] - '0'];
            int y1 = y + dy[v[x][y] - '0'];
            if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m && v[i][j] != 'a') {
                x = x1;
                y = y1;
                g[x][y].push_back({i, j});
                ++indeg[i][j];
            }
        }
    }
    FOR (i, 0, q) {
        cin >> s;
        reverse(IT(s));
        vector <int> a(s.size());
        a[0] = 1 << (s[0] - '0');
        FOR (i, 1, s.size()) {
            a[i] = a[i - 1] | (1 << (s[i] - '0'));
        }
        queue <PII> qu;
        int res = 0;
        FOR (i, 0, n) {
            FOR (j, 0, m) {
                if (indeg[i][j] != 0) {
                    continue;
                }
                int pos = lower_bound(IT(a), numbers[i][j], [] (int x, int mask) {
                    return ((x & mask) == x);
                }) - a.begin();
                res |= dfs(i, j, pos);
            }
        }
        cout << (res ? "YES" : "NO") << endl;
    }
}


#include <bits/stdc++.h>
#ifndef M_PI
#define M_PI 3.14159265359
#endif // M_PI
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define GET(a, n) for (int __i = 0; __i < (n); ++__i) cin >> a[__i];
#define GETM(a, n, m) for (int __i = 0; __i < (n); ++__i) for (int __j = 0; __j < m; ++__j) cin >> a[__i][__j];
#define PRINTM(a, n, m) for (int __i = 0; __i < (n); ++__i) { for (int __j = 0; __j < m; ++__j) cout << a[__i][__j] << " ";  cout << endl; };
#define PRINT(a, n) for (int __i = 0; __i < (n); ++__i) cout << a[__i] << " ";
#define IT(a) a.begin(), a.end()
#define SQR(x) (x) * (x)
#define CASE(a, s) cout << "Case #" << a << ": " << s << endl;
#define DEB(a) cout << #a << " = " << (a) << endl; cout.flush();
#define DEBA(a) for (auto __i: a) cout << __i << " "; cout << endl; cout.flush();
#define IFDEB(b, a) if (b) { cout << #a << " = " << (a) << endl; cout.flush(); }
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
const int MOD = 1000000007;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <vector <PII>>> g;
string s;
vector <string> v;

int dfs(int x, int y, int pos) {
    if (pos + (v[x][y] == s[pos]) == s.size()) {
        return 1;
    }
    for (auto i: g[x][y]) {
        if (dfs(i.first, i.second, pos + (v[x][y] == s[pos]))) {
            return 1;
        }
    }
    return 0;
}

int main()
{
    int n, m, q;
    cin >> n >> m >> q;
    v.resize(n);
    GET(v, n);
    vector <int> dx(10);
    vector <int> dy(10);
    FOR (i, 0, 10) {
        cin >> dx[i] >> dy[i];
    }
    vector <vector <int>> used(n, vector <int> (m));
    vector <vector <int>> numbers(n, vector <int> (m));
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            if (used[i][j]) {
                continue;
            }
            int x = i;
            int y = j;
            vector <PII> num;
            while (!used[x][y]) {
                num.push_back({x, y});
                used[x][y] = 1;
                int x1 = x + dx[v[x][y] - '0'];
                int y1 = y + dy[v[x][y] - '0'];
                if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m) {
                    x = x1;
                    y = y1;
                }
            }
            if (used[x][y] == 2) {
                for (auto i: num) {
                    used[i.first][i.second] = 2;
                }
                continue;
            }
            reverse(IT(num));
            while (num.back() != make_pair(x, y)) {
                used[num.back().first][num.back().second] = 2;
                num.pop_back();
            }
            int mask = 0;
            for (auto l: num) {
                mask |= 1 << (v[l.first][l.second] - '0');
                v[l.first][l.second] = 'a';
            }
            for (auto l: num) {
                numbers[l.first][l.second] = mask;
                used[l.first][l.second] = 2;
            }
        }
    }
    g.resize(n);
    FOR (i, 0, n) {
        g[i].resize(m);
    }
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            if (v[i][j] == 'a') {
                continue;
            }
            int x = i;
            int y = j;
            int x1 = x + dx[v[x][y] - '0'];
            int y1 = y + dy[v[x][y] - '0'];
            if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m && v[i][j] != 'a') {
                x = x1;
                y = y1;
                g[x][y].push_back({i, j});
            }
        }
    }
    FOR (i, 0, q) {
        cin >> s;
        reverse(IT(s));
        vector <int> a(s.size());
        a[0] = 1 << (s[0] - '0');
        FOR (i, 1, s.size()) {
            a[i] = a[i - 1] | (1 << (s[i] - '0'));
        }
        queue <PII> qu;
        int res = 0;
        FOR (i, 0, n) {
            FOR (j, 0, m) {
                int pos = lower_bound(IT(a), numbers[i][j], [] (int x, int mask) {
                    return ((x & mask) == x);
                }) - a.begin();
                res |= dfs(i, j, pos);
            }
        }
        cout << (res ? "YES" : "NO") << endl;
    }
}


#include <bits/stdc++.h>
#ifndef M_PI
#define M_PI 3.14159265359
#endif // M_PI
#define endl "\n"
#define FOR(x, y, z) for (int x = (y); x < (z); ++x)
#define FORR(x, y, z) for (int x = (y); x > (z); --x)
#define GET(a, n) for (int __i = 0; __i < (n); ++__i) cin >> a[__i];
#define GETM(a, n, m) for (int __i = 0; __i < (n); ++__i) for (int __j = 0; __j < m; ++__j) cin >> a[__i][__j];
#define PRINTM(a, n, m) for (int __i = 0; __i < (n); ++__i) { for (int __j = 0; __j < m; ++__j) cout << a[__i][__j] << " ";  cout << endl; };
#define PRINT(a, n) for (int __i = 0; __i < (n); ++__i) cout << a[__i] << " ";
#define IT(a) a.begin(), a.end()
#define SQR(x) (x) * (x)
#define CASE(a, s) cout << "Case #" << a << ": " << s << endl;
#define DEB(a) cout << #a << " = " << (a) << endl; cout.flush();
#define DEBA(a) for (auto __i: a) cout << __i << " "; cout << endl; cout.flush();
#define IFDEB(b, a) if (b) { cout << #a << " = " << (a) << endl; cout.flush(); }
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
typedef vector <vector <int>> VVI;
typedef pair <int, int> PII;
const int MOD = 1000000007;
template <class T> typename T::value_type arr_sum(const T& v, int n) { typename T::value_type sum = 0; FOR(i, 0, n) sum += v[i]; return sum; }
struct Sync_stdio { Sync_stdio() { cin.tie(NULL); ios_base::sync_with_stdio(false); } } _sync_stdio;

vector <vector <vector <PII>>> g;
string s;
vector <string> v;

int dfs(int x, int y, int pos) {
    if (pos + (v[x][y] == s[pos]) == s.size()) {
        return 1;
    }
    for (auto i: g[x][y]) {
        if (dfs(i.first, i.second, pos + (v[x][y] == s[pos]))) {
            return 1;
        }
    }
    return 0;
}

int main()
{
    int n, m, q;
    cin >> n >> m >> q;
    v.resize(n);
    GET(v, n);
    vector <int> dx(10);
    vector <int> dy(10);
    FOR (i, 0, 10) {
        cin >> dx[i] >> dy[i];
    }
    vector <vector <int>> used(n, vector <int> (m));
    vector <vector <int>> numbers(n, vector <int> (m));
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            if (used[i][j]) {
                continue;
            }
            int x = i;
            int y = j;
            vector <PII> num;
            while (!used[x][y]) {
                num.push_back({x, y});
                used[x][y] = 1;
                int x1 = x + dx[v[x][y] - '0'];
                int y1 = y + dy[v[x][y] - '0'];
                if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m) {
                    x = x1;
                    y = y1;
                }
            }
            if (used[x][y] == 2) {
                for (auto i: num) {
                    used[i.first][i.second] = 2;
                }
                continue;
            }
            reverse(IT(num));
            while (num.back() != make_pair(x, y)) {
                used[num.back().first][num.back().second] = 2;
                num.pop_back();
            }
            int mask = 0;
            for (auto l: num) {
                mask |= 1 << (v[l.first][l.second] - '0');
                v[l.first][l.second] = 'a';
            }
            for (auto l: num) {
                numbers[l.first][l.second] = mask;
                used[l.first][l.second] = 2;
            }
        }
    }
    g.resize(n);
    FOR (i, 0, n) {
        g[i].resize(m);
    }
    FOR (i, 0, n) {
        FOR (j, 0, m) {
            int x = i;
            int y = j;
            int x1 = x + dx[v[x][y] - '0'];
            int y1 = y + dy[v[x][y] - '0'];
            if (0 <= x1 && x1 < n && 0 <= y1 && y1 < m && v[i][j] != 'a') {
                x = x1;
                y = y1;
                g[x][y].push_back({i, j});
            }
        }
    }
    /*for (auto i: numbers) {
        for (auto j: i) {
            FOR (k, 0, 10) {
                cout << !!(j & (1 << k));
            }
            cout << " ";
        }
        cout << endl;
    }*/
    FOR (i, 0, q) {
        cin >> s;
        reverse(IT(s));
        vector <int> a(s.size());
        a[0] = 1 << (s[0] - '0');
        FOR (i, 1, s.size()) {
            a[i] = a[i - 1] | (1 << (s[i] - '0'));
        }
        queue <PII> qu;
        int res = 0;
        FOR (i, 0, n) {
            FOR (j, 0, m) {
                int pos = lower_bound(IT(a), numbers[i][j], [] (int x, int mask) {
                    return ((x & mask) == x);
                }) - a.begin();
                res |= dfs(i, j, pos);
            }
        }
        cout << (res ? "YES" : "NO") << endl;
    }
}


#include <bits/stdc++.h>
#include <stdint.h>
using namespace std;

typedef uint8_t byte;
typedef int16_t i16;
typedef uint16_t ui16;
typedef int32_t i32;
typedef uint32_t ui32;
typedef int64_t i64;
typedef uint64_t ui64;
typedef long double ld;
typedef pair<int, int> Pii;

template <typename T>
using V = vector<T>;

typedef V<int> Vi;

#ifndef M_PI
#	define M_PI 3.14159265358979323846
#endif

#ifdef __CLANG
#	define unordered_map map
#	define unordered_set set
#	define to_string(n) string()
#endif

int gcdex(int a, int b, int &x, int &y) {
	if (a == 0) {
		x = 0;
		y = 1;
		return b;
	}

	int x1, y1;
	int g = gcdex(b % a, a, x1, y1);
	x = y1 - (b / a) * x1;
	y = x1;

	return g;
}

#define MOD 1000000007
inline int ADD_MOD(int a, int b) { return (a + b) % MOD; }
inline int MUL_MOD(int a, int b) { return (i64(a) * b) % MOD; }
inline int SUB_MOD(int a, int b) { return a >= b ? a - b : a + MOD - b; }
int DIV_MOD(int a, int b) {
	int x, y;
	gcdex(b, MOD, x, y);

	int b1 = (x % MOD + MOD) % MOD;
	return MUL_MOD(a, b1);
}

const ld EPS = 1. / 1e9;
inline bool EPS_EQUAL(ld a, ld b) { return abs(a - b) <= EPS; }
inline bool EPS_LESS(ld a, ld b) { return b - a > EPS; }
inline bool EPS_GREATER(ld a, ld b) { return a - b > EPS; }

const int INF = 1e9;
const i64 INF64 = 2e18;

const int MAXN = 200;

class Node {
public:
	V<Node> children;

	int val = 0;

	int maxHeight = 1;
	bool vals[10] = {0};
};

class RootNode : public Node {
public:
	bool cycleVals[10] = {0};
};

int n, m;
byte table[MAXN][MAXN];
Pii moves[10];

V<RootNode> trees;
Node* tableNodes[MAXN][MAXN] = {0};

RootNode* addRoot() {
	trees.push_back(RootNode());
	return &trees.back();
}

Node* addNode(Node &parent) {
	parent.children.push_back(Node());
	return &parent.children.back();
}

void copy(bool from[10], bool to[10]) {
	memcpy(to, from, sizeof(bool) * 10);
}

struct BuildTreeInfo {
	Node *parent = nullptr;

	RootNode *cycle = nullptr;
	Pii cycleEnd;
};

BuildTreeInfo buildTree(Pii pos, bool visited[MAXN][MAXN]) {
	BuildTreeInfo res;
	if (visited[pos.first][pos.second]) {
		if (tableNodes[pos.first][pos.second]) {
			res.parent = tableNodes[pos.first][pos.second];
		} else {
			res.cycle = addRoot();
			res.cycleEnd = pos;
		}
		return res;
	}
	visited[pos.first][pos.second] = true;

	byte val = table[pos.first][pos.second];

	Pii &move = moves[val];
	Pii next = {pos.first + move.first, pos.second + move.second};

	if (next.first < 0 || next.first >= n ||
		next.second < 0 || next.second >= m) {

		RootNode* root = addRoot();
		root->cycleVals[val] = 1;
		res.parent = root;

		tableNodes[pos.first][pos.second] = root;
	} else {
		BuildTreeInfo nextRes = buildTree(next, visited);

		if (nextRes.parent) {
			Node *node = addNode(*nextRes.parent);
			node->val = val;
			res.parent = node;

			tableNodes[pos.first][pos.second] = node;
		} else {
			tableNodes[pos.first][pos.second] = nextRes.cycle;
			nextRes.cycle->cycleVals[val] = 1;

			if (nextRes.cycleEnd == pos) {
				res.parent = nextRes.cycle;
			} else {
				res.cycle = nextRes.cycle;
				res.cycleEnd = nextRes.cycleEnd;
			}
		}
	}

	return res;
}

void initTree(Node &node) {
	node.vals[node.val] = 1;

	for (auto &child : node.children) {
		initTree(child);

		node.maxHeight = max(node.maxHeight, child.maxHeight + 1);

		for (int i = 0; i < 10; ++i) {
			if (child.vals[i]) {
				node.vals[i] = 1;
			}
		}
	}
}

bool checkNode(Node &node, string &s, int at) {
	if (node.maxHeight < at) {
		return false;
	}

	byte ch = s[at] - '0';
	if (!node.vals[ch]) {
		return false;
	}

	if (node.val == ch) {
		--at;
		if (at < 0) {
			return true;
		}
	}

	for (auto &child : node.children) {
		if (checkNode(child, s, at)) {
			return true;
		}
	}

	return false;
}

bool query(string &s) {
	int len = s.size();

	V<Pii> a;
	bool am[10] = {0};

	byte last = s[len - 1] - '0';
	am[last] = 1;

	for (int i = len - 1; i >= 0; --i) {
		byte ch = s[i] - '0';
		if (!am[ch]) {
			a.push_back({last, i + 1});

			last = ch;
			am[ch] = 1;
		}
	}
	a.push_back({last, 0});

	for (auto &root : trees) {
		int start = len;
		for (auto &i : a) {
			if (!root.cycleVals[i.first]) {
				break;
			}
			start = i.second;
		}

		if (start == 0) {
			return true;
		}

		for (auto &child : root.children) {
			if (checkNode(child, s, start - 1)) {
				return true;
			}
		}
	}
	return false;
}

void printTree(Node &node, string prefix) {
	cout << prefix << "val: " << node.val << ", maxH: " << node.maxHeight << ", vals: ";
	for (int i = 0; i < 10; ++i) {
		if (node.vals[i]) {
			cout << i << " ";
		}
	}
	cout << endl;

	for (auto &child : node.children) {
		printTree(child, prefix + "  ");
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.precision(15);

	int q;
	cin >> n >> m >> q;

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			char ch;
			cin >> ch;

			table[i][j] = ch - '0';
		}
	}

	for (int i = 0; i < 10; ++i) {
		cin >> moves[i].first >> moves[i].second;
	}

	{
		bool visited[MAXN][MAXN] = {0};
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				if (!visited[i][j]) {
					buildTree({i, j}, visited);
				}
			}
		}
	}

	for (auto &root : trees) {
		initTree(root);
	}

	for (int i = 0; i < q; ++i) {
		string s;
		cin >> s;

		if (query(s)) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <stdint.h>
using namespace std;

typedef uint8_t byte;
typedef int16_t i16;
typedef uint16_t ui16;
typedef int32_t i32;
typedef uint32_t ui32;
typedef int64_t i64;
typedef uint64_t ui64;
typedef long double ld;
typedef pair<int, int> Pii;

template <typename T>
using V = vector<T>;

typedef V<int> Vi;

#ifndef M_PI
#	define M_PI 3.14159265358979323846
#endif

#ifdef __CLANG
#	define unordered_map map
#	define unordered_set set
#	define to_string(n) string()
#endif

int gcdex(int a, int b, int &x, int &y) {
	if (a == 0) {
		x = 0;
		y = 1;
		return b;
	}

	int x1, y1;
	int g = gcdex(b % a, a, x1, y1);
	x = y1 - (b / a) * x1;
	y = x1;

	return g;
}

#define MOD 1000000007
inline int ADD_MOD(int a, int b) { return (a + b) % MOD; }
inline int MUL_MOD(int a, int b) { return (i64(a) * b) % MOD; }
inline int SUB_MOD(int a, int b) { return a >= b ? a - b : a + MOD - b; }
int DIV_MOD(int a, int b) {
	int x, y;
	gcdex(b, MOD, x, y);

	int b1 = (x % MOD + MOD) % MOD;
	return MUL_MOD(a, b1);
}

const ld EPS = 1. / 1e9;
inline bool EPS_EQUAL(ld a, ld b) { return abs(a - b) <= EPS; }
inline bool EPS_LESS(ld a, ld b) { return b - a > EPS; }
inline bool EPS_GREATER(ld a, ld b) { return a - b > EPS; }

const int INF = 1e9;
const i64 INF64 = 2e18;

const int MAXN = 200;

class Node {
public:
	V<Node> children;

	int val = 0;

	int maxHeight = 1;
	bool vals[10] = {0};
};

class RootNode : public Node {
public:
	bool cycleVals[10] = {0};
};

int n, m;
byte table[MAXN][MAXN];
Pii moves[10];

V<RootNode> trees;
Node* tableNodes[MAXN][MAXN] = {0};

RootNode* addRoot() {
	trees.push_back(RootNode());
	return &trees.back();
}

Node* addNode(Node &parent) {
	parent.children.push_back(Node());
	return &parent.children.back();
}

void copy(bool from[10], bool to[10]) {
	memcpy(to, from, sizeof(bool) * 10);
}

struct BuildTreeInfo {
	Node *parent = nullptr;

	RootNode *cycle = nullptr;
	Pii cycleEnd;
};

BuildTreeInfo buildTree(Pii pos, bool visited[MAXN][MAXN]) {
	BuildTreeInfo res;
	if (visited[pos.first][pos.second]) {
		if (tableNodes[pos.first][pos.second]) {
			res.parent = tableNodes[pos.first][pos.second];
		} else {
			res.cycle = addRoot();
			res.cycleEnd = pos;
		}
		return res;
	}
	visited[pos.first][pos.second] = true;

	byte val = table[pos.first][pos.second];

	Pii &move = moves[val];
	Pii next = {pos.first + move.first, pos.second + move.second};

	if (next.first < 0 || next.first >= n ||
		next.second < 0 || next.second >= m) {

		RootNode* root = addRoot();
		root->cycleVals[val] = 1;
		res.parent = root;

		tableNodes[pos.first][pos.second] = root;
	} else {
		BuildTreeInfo nextRes = buildTree(next, visited);

		if (nextRes.parent) {
			Node *node = addNode(*nextRes.parent);
			node->val = val;
			res.parent = node;

			tableNodes[pos.first][pos.second] = node;
		} else {
			tableNodes[pos.first][pos.second] = nextRes.cycle;
			nextRes.cycle->cycleVals[val] = 1;

			if (nextRes.cycleEnd == pos) {
				res.parent = nextRes.cycle;
			} else {
				res.cycle = nextRes.cycle;
				res.cycleEnd = nextRes.cycleEnd;
			}
		}
	}

	return res;
}

void initTree(Node &node) {
	node.vals[node.val] = 1;

	for (auto &child : node.children) {
		initTree(child);

		node.maxHeight = max(node.maxHeight, child.maxHeight + 1);

		for (int i = 0; i < 10; ++i) {
			if (child.vals[i]) {
				node.vals[i] = 1;
			}
		}
	}
}

bool checkNode(Node &node, string &s, int at) {
	if (node.maxHeight < at) {
		return false;
	}

	byte ch = s[at];
	if (!node.vals[ch]) {
		return false;
	}

	if (node.val == at) {
		--at;
		if (at < 0) {
			return true;
		}
	}

	for (auto &child : node.children) {
		if (checkNode(child, s, at)) {
			return true;
		}
	}

	return false;
}

bool query(string &s) {
	int len = s.size();

	V<Pii> a;
	bool am[10] = {0};

	byte last = s[len - 1] - '0';
	am[last] = 1;

	for (int i = len - 1; i >= 0; --i) {
		byte ch = s[i] - '0';
		if (!am[ch]) {
			a.push_back({last, i + 1});

			last = ch;
			am[ch] = 1;
		}
	}
	a.push_back({last, 0});

	for (auto &root : trees) {
		int start = len;
		for (auto &i : a) {
			if (!root.cycleVals[i.first]) {
				break;
			}
			start = i.second;
		}

		if (start == 0) {
			return true;
		}

		for (auto &child : root.children) {
			if (checkNode(child, s, start - 1)) {
				return true;
			}
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.precision(15);

	int q;
	cin >> n >> m >> q;

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			char ch;
			cin >> ch;

			table[i][j] = ch - '0';
		}
	}

	for (int i = 0; i < 10; ++i) {
		cin >> moves[i].first >> moves[i].second;
	}

	{
		bool visited[MAXN][MAXN] = {0};
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				if (!visited[i][j]) {
					buildTree({i, j}, visited);
				}
			}
		}
	}

	for (auto &root : trees) {
		initTree(root);
	}

	for (int i = 0; i < q; ++i) {
		string s;
		cin >> s;

		if (query(s)) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <stdint.h>
using namespace std;

typedef uint8_t byte;
typedef int16_t i16;
typedef uint16_t ui16;
typedef int32_t i32;
typedef uint32_t ui32;
typedef int64_t i64;
typedef uint64_t ui64;
typedef long double ld;
typedef pair<int, int> Pii;

template <typename T>
using V = vector<T>;

typedef V<int> Vi;

#ifndef M_PI
#	define M_PI 3.14159265358979323846
#endif

#ifdef __CLANG
#	define unordered_map map
#	define unordered_set set
#	define to_string(n) string()
#endif

int gcdex(int a, int b, int &x, int &y) {
	if (a == 0) {
		x = 0;
		y = 1;
		return b;
	}

	int x1, y1;
	int g = gcdex(b % a, a, x1, y1);
	x = y1 - (b / a) * x1;
	y = x1;

	return g;
}

#define MOD 1000000007
inline int ADD_MOD(int a, int b) { return (a + b) % MOD; }
inline int MUL_MOD(int a, int b) { return (i64(a) * b) % MOD; }
inline int SUB_MOD(int a, int b) { return a >= b ? a - b : a + MOD - b; }
int DIV_MOD(int a, int b) {
	int x, y;
	gcdex(b, MOD, x, y);

	int b1 = (x % MOD + MOD) % MOD;
	return MUL_MOD(a, b1);
}

const ld EPS = 1. / 1e9;
inline bool EPS_EQUAL(ld a, ld b) { return abs(a - b) <= EPS; }
inline bool EPS_LESS(ld a, ld b) { return b - a > EPS; }
inline bool EPS_GREATER(ld a, ld b) { return a - b > EPS; }

const int INF = 1e9;
const i64 INF64 = 2e18;

const int MAXN = 200;

class Node {
public:
	V<Node*> children;

	int val = 0;

	int maxHeight = 1;
	bool vals[10] = {0};
};

class RootNode : public Node {
public:
	bool cycleVals[10] = {0};
};

int n, m;
byte table[MAXN][MAXN];
Pii moves[10];

V<RootNode*> trees;
Node* tableNodes[MAXN][MAXN] = {0};

RootNode* addRoot() {
	RootNode *root = new RootNode();
	trees.push_back(root);
	return root;
}

Node* addNode(Node &parent) {
	Node *n = new Node();
	parent.children.push_back(n);
	return n;
}

void copy(bool from[10], bool to[10]) {
	memcpy(to, from, sizeof(bool) * 10);
}

struct BuildTreeInfo {
	Node *parent = nullptr;

	RootNode *cycle = nullptr;
	Pii cycleEnd;
};

BuildTreeInfo buildTree(Pii pos, bool visited[MAXN][MAXN]) {
	BuildTreeInfo res;
	if (visited[pos.first][pos.second]) {
		if (tableNodes[pos.first][pos.second]) {
			res.parent = tableNodes[pos.first][pos.second];
		} else {
			res.cycle = addRoot();
			res.cycleEnd = pos;
		}
		return res;
	}
	visited[pos.first][pos.second] = true;

	byte val = table[pos.first][pos.second];

	Pii &move = moves[val];
	Pii next = {pos.first + move.first, pos.second + move.second};

	if (next.first < 0 || next.first >= n ||
		next.second < 0 || next.second >= m) {

		RootNode* root = addRoot();
		root->cycleVals[val] = 1;
		res.parent = root;

		tableNodes[pos.first][pos.second] = root;
	} else {
		BuildTreeInfo nextRes = buildTree(next, visited);

		if (nextRes.parent) {
			Node *node = addNode(*nextRes.parent);
			node->val = val;
			res.parent = node;

			tableNodes[pos.first][pos.second] = node;
		} else {
			tableNodes[pos.first][pos.second] = nextRes.cycle;
			nextRes.cycle->cycleVals[val] = 1;

			if (nextRes.cycleEnd == pos) {
				res.parent = nextRes.cycle;
			} else {
				res.cycle = nextRes.cycle;
				res.cycleEnd = nextRes.cycleEnd;
			}
		}
	}

	return res;
}

void initTree(Node &node) {
	node.vals[node.val] = 1;

	for (auto &child : node.children) {
		initTree(*child);

		node.maxHeight = max(node.maxHeight, child->maxHeight + 1);

		for (int i = 0; i < 10; ++i) {
			if (child->vals[i]) {
				node.vals[i] = 1;
			}
		}
	}
}

bool checkNode(Node &node, string &s, int at) {
	if (node.maxHeight < at) {
		return false;
	}

	byte ch = s[at] - '0';
	if (!node.vals[ch]) {
		return false;
	}

	if (node.val == ch) {
		--at;
		if (at < 0) {
			return true;
		}
	}

	for (auto &child : node.children) {
		if (checkNode(*child, s, at)) {
			return true;
		}
	}

	return false;
}

bool query(string &s) {
	int len = s.size();

	V<Pii> a;
	bool am[10] = {0};

	byte last = s[len - 1] - '0';
	am[last] = 1;

	for (int i = len - 1; i >= 0; --i) {
		byte ch = s[i] - '0';
		if (!am[ch]) {
			a.push_back({last, i + 1});

			last = ch;
			am[ch] = 1;
		}
	}
	a.push_back({last, 0});

	for (auto &root : trees) {
		int start = len;
		for (auto &i : a) {
			if (!root->cycleVals[i.first]) {
				break;
			}
			start = i.second;
		}

		if (start == 0) {
			return true;
		}

		for (auto &child : root->children) {
			if (checkNode(*child, s, start - 1)) {
				return true;
			}
		}
	}
	return false;
}

void printTree(Node &node, string prefix) {
	cout << prefix << "val: " << node.val << ", maxH: " << node.maxHeight << ", vals: ";
	for (int i = 0; i < 10; ++i) {
		if (node.vals[i]) {
			cout << i << " ";
		}
	}
	cout << endl;

	for (auto &child : node.children) {
		printTree(*child, prefix + "  ");
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.precision(15);

	int q;
	cin >> n >> m >> q;

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			char ch;
			cin >> ch;

			table[i][j] = ch - '0';
		}
	}

	for (int i = 0; i < 10; ++i) {
		cin >> moves[i].first >> moves[i].second;
	}

	{
		bool visited[MAXN][MAXN] = {0};
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				if (!visited[i][j]) {
					buildTree({i, j}, visited);
				}
			}
		}
	}

	for (auto &root : trees) {
		initTree(*root);
	}

	for (int i = 0; i < q; ++i) {
		string s;
		cin >> s;

		if (query(s)) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include <bits/stdc++.h>
#include <stdint.h>
using namespace std;

typedef uint8_t byte;
typedef int16_t i16;
typedef uint16_t ui16;
typedef int32_t i32;
typedef uint32_t ui32;
typedef int64_t i64;
typedef uint64_t ui64;
typedef long double ld;
typedef pair<int, int> Pii;

template <typename T>
using V = vector<T>;

typedef V<int> Vi;

#ifndef M_PI
#	define M_PI 3.14159265358979323846
#endif

#ifdef __CLANG
#	define unordered_map map
#	define unordered_set set
#	define to_string(n) string()
#endif

int gcdex(int a, int b, int &x, int &y) {
	if (a == 0) {
		x = 0;
		y = 1;
		return b;
	}

	int x1, y1;
	int g = gcdex(b % a, a, x1, y1);
	x = y1 - (b / a) * x1;
	y = x1;

	return g;
}

#define MOD 1000000007
inline int ADD_MOD(int a, int b) { return (a + b) % MOD; }
inline int MUL_MOD(int a, int b) { return (i64(a) * b) % MOD; }
inline int SUB_MOD(int a, int b) { return a >= b ? a - b : a + MOD - b; }
int DIV_MOD(int a, int b) {
	int x, y;
	gcdex(b, MOD, x, y);

	int b1 = (x % MOD + MOD) % MOD;
	return MUL_MOD(a, b1);
}

const ld EPS = 1. / 1e9;
inline bool EPS_EQUAL(ld a, ld b) { return abs(a - b) <= EPS; }
inline bool EPS_LESS(ld a, ld b) { return b - a > EPS; }
inline bool EPS_GREATER(ld a, ld b) { return a - b > EPS; }

const int INF = 1e9;
const i64 INF64 = 2e18;

const int MAXN = 200;

class Node {
public:
	V<Node> children;

	int val = 0;

	int maxHeight = 1;
	bool vals[10] = {0};
};

class RootNode : public Node {
public:
	bool cycleVals[10] = {0};
};

int n, m;
byte table[MAXN][MAXN];
Pii moves[10];

V<RootNode> trees;
Node* tableNodes[MAXN][MAXN] = {0};

RootNode* addRoot() {
	trees.push_back(RootNode());
	return &trees.back();
}

Node* addNode(Node &parent) {
	parent.children.push_back(Node());
	return &parent.children.back();
}

void copy(bool from[10], bool to[10]) {
	memcpy(to, from, sizeof(bool) * 10);
}

struct BuildTreeInfo {
	Node *parent = nullptr;

	RootNode *cycle = nullptr;
	Pii cycleEnd;
};

BuildTreeInfo buildTree(Pii pos, bool visited[MAXN][MAXN]) {
	BuildTreeInfo res;
	if (visited[pos.first][pos.second]) {
		if (tableNodes[pos.first][pos.second]) {
			res.parent = tableNodes[pos.first][pos.second];
		} else {
			res.cycle = addRoot();
			res.cycleEnd = pos;
		}
		return res;
	}
	visited[pos.first][pos.second] = true;

	byte val = table[pos.first][pos.second];

	Pii &move = moves[val];
	Pii next = {pos.first + move.first, pos.second + move.second};

	if (next.first < 0 || next.first >= n ||
		next.second < 0 || next.second >= m) {

		RootNode* root = addRoot();
		root->cycleVals[val] = 1;
		res.parent = root;

		tableNodes[pos.first][pos.second] = root;
	} else {
		BuildTreeInfo nextRes = buildTree(next, visited);

		if (nextRes.parent) {
			Node *node = addNode(*nextRes.parent);
			node->val = val;
			res.parent = node;

			tableNodes[pos.first][pos.second] = node;
		} else {
			tableNodes[pos.first][pos.second] = nextRes.cycle;
			nextRes.cycle->cycleVals[val] = 1;

			if (nextRes.cycleEnd == pos) {
				res.parent = nextRes.cycle;
			} else {
				res.cycle = nextRes.cycle;
				res.cycleEnd = nextRes.cycleEnd;
			}
		}
	}

	return res;
}

void initTree(Node &node) {
	node.vals[node.val] = 1;

	for (auto &child : node.children) {
		initTree(child);

		node.maxHeight = max(node.maxHeight, child.maxHeight + 1);

		for (int i = 0; i < 10; ++i) {
			if (child.vals[i]) {
				node.vals[i] = 1;
			}
		}
	}
}

bool checkNode(Node &node, string &s, int at) {
	if (node.maxHeight < at) {
		return false;
	}

	byte ch = s[at] - '0';
	if (!node.vals[ch]) {
		return false;
	}

	if (node.val == at) {
		--at;
		if (at < 0) {
			return true;
		}
	}

	for (auto &child : node.children) {
		if (checkNode(child, s, at)) {
			return true;
		}
	}

	return false;
}

bool query(string &s) {
	int len = s.size();

	V<Pii> a;
	bool am[10] = {0};

	byte last = s[len - 1] - '0';
	am[last] = 1;

	for (int i = len - 1; i >= 0; --i) {
		byte ch = s[i] - '0';
		if (!am[ch]) {
			a.push_back({last, i + 1});

			last = ch;
			am[ch] = 1;
		}
	}
	a.push_back({last, 0});

	for (auto &root : trees) {
		int start = len;
		for (auto &i : a) {
			if (!root.cycleVals[i.first]) {
				break;
			}
			start = i.second;
		}

		if (start == 0) {
			return true;
		}

		for (auto &child : root.children) {
			if (checkNode(child, s, start - 1)) {
				return true;
			}
		}
	}
	return false;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.precision(15);

	int q;
	cin >> n >> m >> q;

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			char ch;
			cin >> ch;

			table[i][j] = ch - '0';
		}
	}

	for (int i = 0; i < 10; ++i) {
		cin >> moves[i].first >> moves[i].second;
	}

	{
		bool visited[MAXN][MAXN] = {0};
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				if (!visited[i][j]) {
					buildTree({i, j}, visited);
				}
			}
		}
	}

	for (auto &root : trees) {
		initTree(root);
	}

	for (int i = 0; i < q; ++i) {
		string s;
		cin >> s;

		if (query(s)) {
			cout << "YES" << endl;
		} else {
			cout << "NO" << endl;
		}
	}

	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=205,M=40005;
int n,m,Q,nd,co,dx[15],dy[15];
int id[N][N],a[M],to[M],vis[M];
vector<int> e[M],vec[M];
char s[N][N],ss[1000005];
int q[M],bel[M],ava[M][15];
void solve(){
	scanf("%s",ss+1);
	int len=strlen(ss+1),h=0,t=0;
	For(i,1,nd) bel[i]=-1;
	For(i,1,co){
		int pos=len;
		for (;pos&&ava[i][ss[pos]-'0'];--pos);
		//cout<<pos<<endl;
		if (!pos) return puts("YES"),void(0);
		for (auto j:vec[i]) bel[j]=pos,q[++t]=j;
	}
	while (h!=t){
		int x=q[++h];
		//cout<<x<<' '<<bel[x]<<endl;
		for (auto i:e[x])
			if (bel[i]==-1){
				int nv=bel[x]-((ss[bel[x]]-'0')==a[i]);
				if (!nv) return puts("YES"),void(0);
				bel[i]=nv; q[++t]=i;
			}
	}
	puts("NO");
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&m,&Q);
	For(i,1,n) scanf("%s",s[i]+1);
	For(i,0,9) scanf("%d%d",&dx[i],&dy[i]);
	For(i,1,n) For(j,1,m)
		id[i][j]=++nd,a[nd]=s[i][j]-'0';
	For(i,1,n) For(j,1,m){
		int c=s[i][j]-'0';
		int nx=i+dx[c],ny=j+dy[c];
		if (nx<1||ny<1||nx>n||ny>m) nx=i,ny=j;
		to[id[i][j]]=id[nx][ny];
		//cout<<id[i][j]<<' '<<id[nx][ny]<<endl;
	}
	For(i,1,nd) e[to[i]].PB(i);
	For(i,1,nd) if (!vis[i]){
		int x=i; ++*vis;
		for (;!vis[x];x=to[x]) vis[x]=*vis;
		if (vis[x]!=*vis) continue;
		//cout<<i<<' '<<x<<endl;
		++co;
		for (int y=x;;){
			//cout<<co<<' '<<y<<endl;
			ava[co][a[y]]=1;
			vec[co].PB(y);
			if (to[y]==x) break;
			y=to[y];
		}
	}
	while (Q--) solve();
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=205,M=40005;
int n,m,Q,nd,co,dx[15],dy[15];
int id[N][N],a[M],to[M],vis[M];
vector<int> e[M],vec[M];
char s[N][N],ss[1000005];
int q[M],bel[M],ava[M][15];
void solve(){
	scanf("%s",ss+1);
	int len=strlen(ss+1),h=0,t=0;
	For(i,1,nd) bel[i]=-1;
	For(i,1,co){
		int pos=len;
		for (;pos&&ava[i][ss[pos]-'0'];--pos);
		if (!pos) return puts("YES"),void(0);
		for (auto j:e[i]) bel[j]=pos,q[++t]=j;
	}
	while (h!=t){
		int x=q[++h];
		for (auto i:e[x])
			if (bel[i]==-1){
				int nv=bel[x]-((ss[bel[x]]-'0')==a[i]);
				if (!nv) return puts("YES"),void(0);
				bel[i]=nv; q[++t]=i;
			}
	}
	puts("NO");
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&m,&Q);
	For(i,1,n) scanf("%s",s[i]+1);
	For(i,0,9) scanf("%d%d",&dx[i],&dy[i]);
	For(i,1,n) For(j,1,m)
		id[i][j]=++nd,a[nd]=s[i][j]-'0';
	For(i,1,n) For(j,1,m){
		int c=s[i][j]-'0';
		int nx=i+dx[c],ny=j+dy[c];
		if (nx<1||ny<1||nx>n||ny>m) nx=i,ny=j;
		to[id[i][j]]=id[nx][ny];
		//cout<<id[i][j]<<' '<<id[nx][ny]<<endl;
	}
	For(i,1,nd) e[to[i]].PB(i);
	For(i,1,nd) if (!vis[i]){
		int x=i; ++*vis;
		for (;!vis[x];x=to[x]) vis[x]=*vis;
		if (vis[x]!=*vis) continue;
		//cout<<i<<' '<<x<<endl;
		++co;
		for (int y=x;;){
			ava[co][a[y]]=1;
			vec[co].PB(y);
			if (to[y]==x) break;
			y=to[y];
		}
	}
	while (Q--) solve();
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
const int N=205,M=40005;
int n,m,Q,nd,co,dx[15],dy[15];
int id[N][N],a[M],to[M],vis[M];
vector<int> e[M],vec[M];
char s[N][N],ss[1000005];
int q[M],bel[M],ava[M][15];
void solve(){
	scanf("%s",ss+1);
	int len=strlen(ss+1),h=0,t=0;
	For(i,1,nd) bel[i]=-1;
	For(i,1,co){
		int pos=len;
		for (;pos&&ava[i][ss[pos]-'0'];--pos);
		if (!pos) return puts("YES"),void(0);
		for (auto j:e[i]) bel[j]=pos,q[++t]=j;
	}
	while (h!=t){
		int x=q[++h];
		for (auto i:e[x])
			if (bel[i]==-1){
				int nv=bel[x]-((ss[bel[x]]-'0')==a[i]);
				if (!nv) return puts("YES"),void(0);
				bel[i]=x; q[++t]=i;
			}
	}
	puts("NO");
}
int main(){
	//freopen("1.in","r",stdin);
	scanf("%d%d%d",&n,&m,&Q);
	For(i,1,n) scanf("%s",s[i]+1);
	For(i,0,9) scanf("%d%d",&dx[i],&dy[i]);
	For(i,1,n) For(j,1,m)
		id[i][j]=++nd,a[nd]=s[i][j]-'0';
	For(i,1,n) For(j,1,m){
		int c=s[i][j]-'0';
		int nx=i+dx[c],ny=j+dy[c];
		if (nx<1||ny<1||nx>n||ny>m) nx=i,ny=j;
		to[id[i][j]]=id[nx][ny];
		//cout<<id[i][j]<<' '<<id[nx][ny]<<endl;
	}
	For(i,1,nd) e[to[i]].PB(i);
	For(i,1,nd) if (!vis[i]){
		int x=i; ++*vis;
		for (;!vis[x];x=to[x]) vis[x]=*vis;
		if (vis[x]!=*vis) continue;
		//cout<<i<<' '<<x<<endl;
		++co;
		for (int y=x;;){
			ava[co][a[y]]=1;
			vec[co].PB(y);
			if (to[y]==x) break;
			y=to[y];
		}
	}
	while (Q--) solve();
}


//
//  main.cpp
//  Algorithm
//
//  Created by Luke Lee on 2015. 12. 31..
//  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};
            }
        }
    }
    cycle_n = 1;
    cycle.resize(1);
    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 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]);
                    }
                }
                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;
                    }
                }
            }
        }

        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 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]);
                    }
                }
                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;
}


//
//  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;
};

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++)
        {
            next_move[y][x] = {y + d[table[y][x] - '0'].y, x + d[table[y][x] - '0'].x};
            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.y != y || v.x != x; 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. 4..
//  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)
    {
        _coord ans;
        ans.y = y + right.y;
        ans.x = x + right.x;
        return ans;
    }
    _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...
    for (int y = 1; y <= SIZE; y++)
    {
        for (int x = 1; x <= SIZE; x++)
        {
            cycle_idx[y][x] = -1;
        }
    }

    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++)
        {
            _coord cur = {y, x};
            if (!visited[y][x])
            {
                dfs_cycle(cur);
            }
            if (in_cycle[y][x] && cycle_idx[y][x] < 0)
            {
                cycle_idx[y][x] = cycle_n;

                cycle.resize(cycle.size() + 1);
                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 = 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)
    {
        _coord ans;
        ans.y = y + right.y;
        ans.x = x + right.x;
        return ans;
    }
    _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. 3..
//  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)
    {
        _coord ans;
        ans.y = y + right.y;
        ans.x = x + right.x;
        return ans;
    }
    _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...
    for (int y = 1; y <= SIZE; y++)
    {
        for (int x = 1; x <= SIZE; x++)
        {
            cycle_idx[y][x] = -1;
        }
    }

    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] < 0)
            {
                cycle.resize(cycle.size() + 1);

                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 = 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++)
        {
            _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;
}


//
//  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};
            }
        }
    }
    cycle_n = 1;
    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 2016. 2. 4..
//  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)
    {
        _coord ans;
        ans.y = y + right.y;
        ans.x = x + right.x;
        return ans;
    }
    _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];
int 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...
    for (int y = 1; y <= SIZE; y++)
    {
        for (int x = 1; x <= SIZE; x++)
        {
            cycle_idx[y][x] = -1;
        }
    }

    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++)
        {
            _coord cur = {y, x};
            if (!visited[y][x])
            {
                visited[y][x] = (y - 1) * size_x + (x - 1) + 1;
                dfs_cycle(cur);
            }
            if (in_cycle[y][x] && cycle_idx[y][x] < 0)
            {
                cycle_idx[y][x] = cycle_n;
                cycle.resize(cycle.size() + 1);
                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 (cycle_idx[y][x] < 0) 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)
{
    _coord v = next_move[u.y][u.x];
    if (!visited[v.y][v.x])
    {
        visited[v.y][v.x] = visited[u.y][u.x];
        dfs_cycle(v);
    }
    else if (visited[v.y][v.x] == visited[u.y][u.x])
    {
        in_cycle[v.y][v.x] = true;
    }
}

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;
}