// Written by Kuji on 2020-04-20-17.52.46
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    string s;
    int k,i,n,a=0;
    cin>>n>>k;
    while(n--)
    {
        cin>>s;
        sort(s.begin(),s.end());
        set<char> c;
        for(i=0;i<s.length();i++)
        {
            if(s[i]-48>k)
                break;
            else
            c.insert(s[i]);
        }
        if(c.size()==k+1)
            a++;
    }
    cout<<a<<"\n";
}


// Written by Kuji on 2020-04-15-12.15.36
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    int n,k,c=0;
    cin>>n>>k;
    while(n--)
    {
        string s;
        cin>>s;
        set<int> s1;
        for(int i=0;i<s.length();i++)
        {
            s1.insert(s[i]-48);
        }
        int j=0,f;
        for(auto it=s1.begin();it!=s1.end();it++)
        {   f=0;
            if(*(it)==j&&j<=k)
            {
                f=1;
                if(j==k)
                    break;
            }
            else
            {
                f=0;
                break;
            }
            j++;

        }
        if(f)
            c++;

    }
    cout<<c<<"\n";
}


// Written by Kuji on 2020-04-20-17.52.46
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    string s;
    int k,i,n,a=0;
    cin>>n>>k;
    while(n--)
    {
        cin>>s;
        set<char> c;
        for(i=0;i<s.length();i++)
        {
            if(s[i]-48>k)
                break;
            else
            c.insert(s[i]);
        }
        if(c.size()==k+1)
            a++;
    }
    cout<<a<<"\n";
}


// Written by Kuji on 2020-04-15-12.15.36
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    int n,k,c=0;
    cin>>n>>k;
    while(n--)
    {
        string s;
        cin>>s;
        set<int> s1;
        for(int i=0;i<s.length();i++)
        {
            s1.insert(s[i]-48);
        }
        auto it=s1.end();
        it--;
        if(s1.size()==k+1&&(*it)==k)
            c++;
    }
    cout<<c<<"\n";
}


// Written by Kuji on 2020-04-20-17.52.46
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    string s;
    int k,i,n,c=0;
    cin>>n>>k;
    while(n--)
    {
        cin>>s;
        int f=1;
        sort(s.begin(),s.end());
        for(i=0;i<=k;i++)
        {
            if(s[i]-48==i)
                continue;
            else
            {
                f=0;
                break;
            }
        }
        if(f)
            c++;
    }
    cout<<c<<"\n";
}


// Written by Kuji on 2020-04-20-17.52.46
#include<bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(0);ios_base::sync_with_stdio(false);
    string s;
    int k,i,n,a=0;
    cin>>n>>k;
    while(n--)
    {
        cin>>s;
        set<char> c;
        for(i=0;i<s.length();i++)
        {
            c.insert(s[i]);
        }
        int f=1;
        set<char> ::iterator it=c.begin();
        for(it,i=0;it!=c.end()&&i<=k;it++,i++)
        {
            if(*it-48==i)
                continue;
            else
            {
                f=0;
                break;
            }
        }
        if(f)
            a++;
    }
    cout<<a<<"\n";
}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<iomanip>
#include<unordered_set>
#include<deque>
using namespace std;
set<int>s1;
vector<int>v1;
vector<int>v2;
pair<char, int>p1[100005];

int main()
{
	int n,xx=0,counter=0, m; cin >> n >> m;
	xx = (m*(m + 1)) / 2;
	for (int i = 0; i < n; i++)
	{
		bool f = true;
		string x; cin >> x;
		sort(x.begin(), x.end());
		for (int j = 0; j <= m; j++)
		{
			if (x[j]-'0' >m){ f = false; break; }

		}
		if (f && x.size()>=(m+1)){ counter++; }

	}

	cout << counter << endl;

}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<iomanip>
#include<unordered_set>
#include<deque>
using namespace std;
set<int>s1;
vector<int>v1;
vector<int>v2;
pair<char, int>p1[100005];
int sum = 0,a=0;
void fair(int x)
{
	if (x > 0)
	{
		v1.push_back(x % 10);
		fair(x / 10);

	}
	else { return; }

}
int main()
{
	int n,xx=0,counter=0, m; cin >> n >> m;
	xx = (m*(m + 1)) / 2;
	for (int i = 0; i < n; i++)
	{
		bool f = true;
		int x; cin >> x; fair(x);
		sort(v1.begin(), v1.end());
		for (int j = 0; j <= m; j++)
		{
			if (v1[j] >m){ f = false; break; }

		}
		if (f){ counter++; }
		v1.clear();

	}

	cout << counter << endl;

}


#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<iomanip>
#include<unordered_set>
#include<deque>
using namespace std;
set<int>s1;
vector<int>v1;
vector<int>v2;
pair<char, int>p1[100005];

int main()
{
	int n,xx=0,counter=0, m; cin >> n >> m;
	xx = (m*(m + 1)) / 2;
	for (int i = 0; i < n; i++)
	{

		string x; cin >> x;
		sort(x.begin(), x.end());
		for (int j = 0; j < x.size(); j++)
		{
			if (x[j]-'0' >m){ break; }
			else { s1.insert(x[j]); }

		}
		if ( s1.size()==(m+1)){ counter++; }
		s1.clear();
	}

	cout << counter << endl;

}


#include"stdafx.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<iomanip>
#include<unordered_set>
#include<deque>
using namespace std;
set<int>s1;
vector<int>v1;
vector<int>v2;
pair<char, int>p1[100005];
int main()
{
	int n,counter=0, m; cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		string s; cin >> s;
		if (s.size() >= m + 1) { counter++; }

	}

	cout << counter;

}


    /** ` Micro Mezzo Macro Flation -- Overheated Economy ., **/

    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <bitset>
    #include <list>
    #include <set>
    #include <map>
    #include <queue>

    using namespace std;

    #define REP(i, n) for (int i=0;i<int(n);++i)
    #define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
    #define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
    #define REP_1(i, n) for (int i=1;i<=int(n);++i)
    #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
    #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
    #define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
    #define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
    #define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
    #define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
    #define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
    #define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
    #define DO(n) while(n--)
    #define DO_C(n) int n____ = n; while(n____--)
    #define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
    #define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
    #define SQZ(i, j, a, b) for (int i=int(a),j=int(b)-1;i<j;++i,--j)
    #define SQZ_1(i, j, a, b) for (int i=int(a),j=int(b);i<=j;++i,--j)
    #define REP_2(i, j, n, m) REP(i, n) REP(j, m)
    #define For_each(it, A) for (set<char>::iterator it = A.begin(); it != A.end(); ++it)

    #define ALL(A) A.begin(), A.end()
    #define LLA(A) A.rbegin(), A.rend()
    #define CPY(A, B) memcpy(A, B, sizeof(A))
    #define INS(A, P, B) A.insert(A.begin() + P, B)
    #define ERS(A, P) A.erase(A.begin() + P)
    #define BSC(A, X) find(ALL(A), X) // != A.end()
    #define CTN(T, x) T.find(x) != T.end()
    #define SZ(A) int(A.size())
    #define PB push_back
    #define MP(A, B) make_pair(A, B)

    #define Rush int T____; RD(T____); DO(T____)
    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #define Ruby system("ruby main.rb")
    #define Haskell system("runghc main.hs")
    #define Pascal system("fpc main.pas")

    typedef long long LL;
    typedef double DB;
    typedef unsigned UINT;
    typedef unsigned long long ULL;

    typedef vector<int> VI;
    typedef vector<string> VS;
    typedef vector<LL> VL;
    typedef vector<DB> VD;
    typedef set<int> SI;
    typedef set<string> SS;
    typedef set<LL> SL;
    typedef set<DB> SD;
    typedef map<int, int> MII;
    typedef map<string, int> MSI;
    typedef map<LL, int> MLI;
    typedef map<DB, int> MDI;
    typedef map<int, bool> MIB;
    typedef map<string, bool> MSB;
    typedef map<LL, bool> MLB;
    typedef map<DB, bool> MDB;
    typedef pair<int, int> PII;
    typedef pair<int, bool> PIB;
    typedef vector<PII> VII;
    typedef vector<VI> VVI;
    typedef vector<VII> VVII;
    typedef set<PII> SII;
    typedef map<PII, int> MPIII;
    typedef map<PII, bool> MPIIB;

    /** I/O Accelerator **/

    /* ... :" We are I/O Accelerator ... Use us at your own risk ;) ... " .. */

    template<class T> inline void RD(T &);
    template<class T> inline void OT(const T &);

    template<class T> inline T& _RD(T &x){ RD(x); return x;}
    inline int RD(){ int x; RD(x); return x;}
    inline LL RD_LL(){ LL x; RD(x); return x;}
    inline DB RD_DB(){ DB x; RD(x); return x;}

    template<class T0, class T1> inline void RD(T0 &x0, T1 &x1){RD(x0), RD(x1);}
    template<class T0, class T1, class T2> inline void RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2);}
    template<class T0, class T1, class T2, class T3> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3);}
    template<class T0, class T1, class T2, class T3, class T4> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);}
    template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);}
    template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);}
    template<class T0, class T1> inline void OT(T0 &x0, T1 &x1){OT(x0), OT(x1);}
    template<class T0, class T1, class T2> inline void OT(T0 &x0, T1 &x1, T2 &x2){OT(x0), OT(x1), OT(x2);}
    template<class T0, class T1, class T2, class T3> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
    template<class T0, class T1, class T2, class T3, class T4> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
    template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
    template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}

    template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
    template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
    template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
    template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
    template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
    template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
    template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
    template<class T> inline void CLR(T &A){A.clear();}
    template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
    template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
    template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
    template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
    template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
    template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
    template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}
    template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
    template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
    template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2){FLC(A0), FLC(A1), FLC(A2);}
    template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3){FLC(A0), FLC(A1), FLC(A2), FLC(A3);}
    template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4);}
    template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5);}
    template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5), FLC(A6);}

    template<class T> inline void SRT(T &A){sort(ALL(A));}
    template<class T, class C> inline void SRT(T &A, C B){sort(ALL(A), B);}

    /** Add - On **/

    const int MOD = 1000000007;
    const int INF = 0x7fffffff;
    const DB PI = acos(-1.0);
    const DB EPS = 1e-6;
    const DB OO = 1e15;

    // <<= ` 0. Daily Use .,

    template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
    template<class T> inline void checkMax(T &a,const T b){if (b>a) a=b;}
    template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
    template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
    template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
    template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
    template<class T> inline T sqr(T a){return a*a;}
    template<class T> inline T cub(T a){return a*a*a;}
    int Ceil(int x, int y){return (x - 1) / y + 1;}

    // <<= ` 1. Bitwise Operation .,

    inline bool _1(int x, int i){return x & 1<<i;}
    inline int _1(int i){return 1<<i;}
    inline int _U(int i){return _1(i) - 1;};

    inline int count_bits(int x){
        x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
        x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
        x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
        x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
        x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
        return x;
    }

    template<class T> inline T low_bit(T x) {
        return x & -x;
    }

    template<class T> inline T high_bit(T x) {
        T p = low_bit(x);
        while (p != x) x -= p, p = low_bit(x);
        return p;
    }

    // <<= ` 2. Modular Arithmetic Basic .,

    inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
    inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}
    inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
    inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
    inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
    inline int pdt(int a, int b){return (LL)a * b % MOD;}

    // <<= ' 0. I/O interface .,

    template<class T> inline void RD(T &x){
        //cin >> x;
        //scanf("%d", &x);
        char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
        //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';

    }

    int ____Case;
    template<class T> inline void OT(const T &x){
        //cout << x << endl;
        //printf("%d\n", x);
        //printf("%.2lf\n", x);
        printf("Case %d: %d\n", ++____Case, x);
    }

    /* .................................................................................................................................. */

    const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

    const int N = 1001, L = 100001;

    PII I[L]; char maze[N][N]; set<char> Res;
    int n, m, l; char a; int b;

    bool bfs(int x, int y){
        REP(i, l){
            DO_C(I[i].second){
                x = x + dx[I[i].first], y = y + dy[I[i].first] ;
                if (maze[x][y] == '#') return false;
            }
        }
        return true;
    }

    int main(){

        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        //ios::sync_with_stdio(false);

        //while (scanf("%d", &n) != EOF){

        RD(n, m); REP_2(i, j, n, m) scanf(" %c", &maze[i][j]);

        int x = 0, y = 0, up = 0, bottom = 0, left = 0, right = 0;
        RD(l); REP(i, l){
            scanf(" %c", &a); I[i].first = a == 'E' ? 0 : a == 'S' ? 1 : a == 'W' ? 2 : 3;
            RD(I[i].second), x += dx[I[i].first] * I[i].second, y += dy[I[i].first] * I[i].second;
            checkMin(up, x), checkMax(bottom, x), checkMin(left, y), checkMax(right, y);
        }

        FOR(x, abs(up), n - bottom) FOR(y, abs(left), m - right)

        //REP(x, n) REP(y, m)

         if ('A' <= maze[x][y] && maze[x][y] <= 'Z'){
            if (bfs(x, y)) Res.insert(maze[x][y]);
        }

        if (Res.empty()){
            cout << "no solution" << endl;
        }
        else {
            For_each(it, Res) cout << *it;
            cout << endl;
        }

    }


/** ` Micro Mezzo Macro Flation -- Overheated Economy ., **/

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <bitset>
#include <list>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
#define DO(n) while(n--)
#define DO_C(n) int n____ = n; while(n____--)
#define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
#define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
#define SQZ(i, j, a, b) for (int i=int(a),j=int(b)-1;i<j;++i,--j)
#define SQZ_1(i, j, a, b) for (int i=int(a),j=int(b);i<=j;++i,--j)
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)
#define For_each(it, A) for (set<char>::iterator it = A.begin(); it != A.end(); ++it)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define BSC(A, X) find(ALL(A), X) // != A.end()
#define CTN(T, x) T.find(x) != T.end()
#define SZ(A) int(A.size())
#define PB push_back
#define MP(A, B) make_pair(A, B)

#define Rush int T____; RD(T____); DO(T____)
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#define Ruby system("ruby main.rb")
#define Haskell system("runghc main.hs")
#define Pascal system("fpc main.pas")

typedef long long LL;
typedef double DB;
typedef unsigned UINT;
typedef unsigned long long ULL;

typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VD;
typedef set<int> SI;
typedef set<string> SS;
typedef set<LL> SL;
typedef set<DB> SD;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef map<LL, int> MLI;
typedef map<DB, int> MDI;
typedef map<int, bool> MIB;
typedef map<string, bool> MSB;
typedef map<LL, bool> MLB;
typedef map<DB, bool> MDB;
typedef pair<int, int> PII;
typedef pair<int, bool> PIB;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;
typedef set<PII> SII;
typedef map<PII, int> MPIII;
typedef map<PII, bool> MPIIB;

/** I/O Accelerator **/

/* ... :" We are I/O Accelerator ... Use us at your own risk ;) ... " .. */

template<class T> inline void RD(T &);
template<class T> inline void OT(const T &);

template<class T> inline T& _RD(T &x){ RD(x); return x;}
inline int RD(){ int x; RD(x); return x;}
inline LL RD_LL(){ LL x; RD(x); return x;}
inline DB RD_DB(){ DB x; RD(x); return x;}

template<class T0, class T1> inline void RD(T0 &x0, T1 &x1){RD(x0), RD(x1);}
template<class T0, class T1, class T2> inline void RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2);}
template<class T0, class T1, class T2, class T3> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);}
template<class T0, class T1> inline void OT(T0 &x0, T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(T0 &x0, T1 &x1, T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T> inline void CLR(T &A){A.clear();}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2){FLC(A0), FLC(A1), FLC(A2);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3){FLC(A0), FLC(A1), FLC(A2), FLC(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5), FLC(A6);}

template<class T> inline void SRT(T &A){sort(ALL(A));}
template<class T, class C> inline void SRT(T &A, C B){sort(ALL(A), B);}

/** Add - On **/

const int MOD = 1000000007;
const int INF = 0x7fffffff;
const DB PI = acos(-1.0);
const DB EPS = 1e-6;
const DB OO = 1e15;

// <<= ` 0. Daily Use .,

template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
template<class T> inline void checkMax(T &a,const T b){if (b>a) a=b;}
template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
int Ceil(int x, int y){return (x - 1) / y + 1;}

// <<= ` 1. Bitwise Operation .,

inline bool _1(int x, int i){return x & 1<<i;}
inline int _1(int i){return 1<<i;}
inline int _U(int i){return _1(i) - 1;};

inline int count_bits(int x){
    x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
    x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
    x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
    x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
    x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
    return x;
}

template<class T> inline T low_bit(T x) {
    return x & -x;
}

template<class T> inline T high_bit(T x) {
    T p = low_bit(x);
    while (p != x) x -= p, p = low_bit(x);
    return p;
}

// <<= ` 2. Modular Arithmetic Basic .,

inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}
inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
inline int pdt(int a, int b){return (LL)a * b % MOD;}

// <<= ' 0. I/O interface .,

template<class T> inline void RD(T &x){
    //cin >> x;
    //scanf("%d", &x);
    char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
    //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';

}

int ____Case;
template<class T> inline void OT(const T &x){
    //cout << x << endl;
    //printf("%d\n", x);
    //printf("%.2lf\n", x);
    printf("Case %d: %d\n", ++____Case, x);
}

/* .................................................................................................................................. */

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

const int N = 1001, L = 101;

PII I[L]; char maze[N][N]; set<char> Res;
int n, m, l; char a; int b;

void bfs(int x, int y){

    //cout << x << " " << y << endl;

    REP(i, l){
        DO(I[i].second){
            int xx = x + dx[I[i].first], yy = y + dy[I[i].first] ;
            if (maze[xx][yy] == '#') break;
            x = xx, y = yy;
        }
     //   cout << " " << x << ' ' << y << endl;
    }

    if ('A' <= maze[x][y] && maze[x][y] <= 'Z'){
        //cout << x << " " << y << endl;
        //cout << maze[x][y] << endl;
        Res.insert(maze[x][y]);
    }
}

int main(){

    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    //ios::sync_with_stdio(false);

    //while (scanf("%d", &n) != EOF){

    RD(n, m); REP_2(i, j, n, m) scanf(" %c", &maze[i][j]);

    RD(l); REP(i, l){
        scanf(" %c", &a); I[i].first = a == 'E' ? 0 : a == 'S' ? 1 : a == 'W' ? 2 : 3;
        RD(I[i].second);
    }
    --I[0].second;

    REP_2(i, j, n, m) if (maze[i][j] == '#'){
        int x = i + dx[I[0].first], y = j + dy[I[0].first] ;
        if (x >= 0 && y >= 0 && x < n && y < m && maze[x][y] != '#') bfs(x, y);
    }

    if (Res.empty()){
        cout << "no solution" << endl;
    }
    else {
        For_each(it, Res) cout << *it;
        cout << endl;
    }

}


/** ` Micro Mezzo Macro Flation -- Overheated Economy ., **/

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <bitset>
#include <list>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
#define DO(n) while(n--)
#define DO_C(n) int n____ = n; while(n____--)
#define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
#define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
#define SQZ(i, j, a, b) for (int i=int(a),j=int(b)-1;i<j;++i,--j)
#define SQZ_1(i, j, a, b) for (int i=int(a),j=int(b);i<=j;++i,--j)
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define BSC(A, X) find(ALL(A), X) // != A.end()
#define CTN(T, x) T.find(x) != T.end()
#define SZ(A) int(A.size())
#define PB push_back
#define MP(A, B) make_pair(A, B)

#define Rush int T____; RD(T____); DO(T____)
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#define Ruby system("ruby main.rb")
#define Haskell system("runghc main.hs")
#define Pascal system("fpc main.pas")

typedef long long LL;
typedef double DB;
typedef unsigned UINT;
typedef unsigned long long ULL;

typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VD;
typedef set<int> SI;
typedef set<string> SS;
typedef set<LL> SL;
typedef set<DB> SD;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef map<LL, int> MLI;
typedef map<DB, int> MDI;
typedef map<int, bool> MIB;
typedef map<string, bool> MSB;
typedef map<LL, bool> MLB;
typedef map<DB, bool> MDB;
typedef pair<int, int> PII;
typedef pair<int, bool> PIB;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;
typedef set<PII> SII;
typedef map<PII, int> MPIII;
typedef map<PII, bool> MPIIB;

/** I/O Accelerator **/

/* ... :" We are I/O Accelerator ... Use us at your own risk ;) ... " .. */

template<class T> inline void RD(T &);
template<class T> inline void OT(const T &);

template<class T> inline T& _RD(T &x){ RD(x); return x;}
inline int RD(){ int x; RD(x); return x;}
inline LL RD_LL(){ LL x; RD(x); return x;}
inline DB RD_DB(){ DB x; RD(x); return x;}

template<class T0, class T1> inline void RD(T0 &x0, T1 &x1){RD(x0), RD(x1);}
template<class T0, class T1, class T2> inline void RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2);}
template<class T0, class T1, class T2, class T3> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);}
template<class T0, class T1> inline void OT(T0 &x0, T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(T0 &x0, T1 &x1, T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T> inline void CLR(T &A){A.clear();}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2){FLC(A0), FLC(A1), FLC(A2);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3){FLC(A0), FLC(A1), FLC(A2), FLC(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5), FLC(A6);}

template<class T> inline void SRT(T &A){sort(ALL(A));}
template<class T, class C> inline void SRT(T &A, C B){sort(ALL(A), B);}

/** Add - On **/

const int MOD = 1000000007;
const int INF = 0x7fffffff;
const DB PI = acos(-1.0);
const DB EPS = 1e-6;
const DB OO = 1e15;

// <<= ` 0. Daily Use .,

template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
template<class T> inline void checkMax(T &a,const T b){if (b>a) a=b;}
template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
int Ceil(int x, int y){return (x - 1) / y + 1;}

// <<= ` 1. Bitwise Operation .,

inline bool _1(int x, int i){return x & 1<<i;}
inline int _1(int i){return 1<<i;}
inline int _U(int i){return _1(i) - 1;};

inline int count_bits(int x){
    x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
    x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
    x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
    x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
    x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
    return x;
}

template<class T> inline T low_bit(T x) {
    return x & -x;
}

template<class T> inline T high_bit(T x) {
    T p = low_bit(x);
    while (p != x) x -= p, p = low_bit(x);
    return p;
}

// <<= ` 2. Modular Arithmetic Basic .,

inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}
inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
inline int pdt(int a, int b){return (LL)a * b % MOD;}

// <<= ' 0. I/O interface .,

template<class T> inline void RD(T &x){
    //cin >> x;
    //scanf("%d", &x);
    char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
    //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';

}

int ____Case;
template<class T> inline void OT(const T &x){
    //cout << x << endl;
    //printf("%d\n", x);
    //printf("%.2lf\n", x);
    printf("Case %d: %d\n", ++____Case, x);
}

#define For_each(it, A) for (set<char>::iterator it = A.begin(); it != A.end(); ++it)
#define For_each_(it, A) for (SII::iterator it = A.begin(); it != A.end(); ++it)
/* .................................................................................................................................. */

const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
const int N = 1001, L = 100001;

SII S; char maze[N][N]; set<char> Res;
int n, m, l; char a; int b, d;

bool bfs(int x, int y){
    For_each_(it, S){
        int xx = x + it->first, yy = y + it->second ;
        if (maze[xx][yy] == '#') return false;
    }
    return true;
}

int main(){

    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    //ios::sync_with_stdio(false);
    //while (scanf("%d", &n) != EOF){

    RD(n, m); REP_2(i, j, n, m) scanf(" %c", &maze[i][j]);

    int x = 0, y = 0, up = 0, bottom = 0, left = 0, right = 0;
    RD(l); REP(i, l){
        scanf(" %c", &a); d = a == 'E' ? 0 : a == 'S' ? 1 : a == 'W' ? 2 : 3;
        DO_C(RD()) x += dx[d], y += dy[d], S.insert(MP(x, y));
        checkMin(up, x), checkMax(bottom, x), checkMin(left, y), checkMax(right, y);
    }

    FOR(x, abs(up), n - bottom) FOR(y, abs(left), m - right) if ('A' <= maze[x][y] && maze[x][y] <= 'Z'){
        if (bfs(x, y)) Res.insert(maze[x][y]);
    }

    if (Res.empty()){
        cout << "no solution" << endl;
    }
    else {
        For_each(it, Res) cout << *it;
        cout << endl;
    }
}


/** ` Micro Mezzo Macro Flation -- Overheated Economy ., **/

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <bitset>
#include <list>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
#define DO(n) while(n--)
#define DO_C(n) int n____ = n; while(n____--)
#define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
#define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
#define SQZ(i, j, a, b) for (int i=int(a),j=int(b)-1;i<j;++i,--j)
#define SQZ_1(i, j, a, b) for (int i=int(a),j=int(b);i<=j;++i,--j)
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)
#define For_each(it, A) for (set<char>::iterator it = A.begin(); it != A.end(); ++it)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define BSC(A, X) find(ALL(A), X) // != A.end()
#define CTN(T, x) T.find(x) != T.end()
#define SZ(A) int(A.size())
#define PB push_back
#define MP(A, B) make_pair(A, B)

#define Rush int T____; RD(T____); DO(T____)
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#define Ruby system("ruby main.rb")
#define Haskell system("runghc main.hs")
#define Pascal system("fpc main.pas")

typedef long long LL;
typedef double DB;
typedef unsigned UINT;
typedef unsigned long long ULL;

typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VD;
typedef set<int> SI;
typedef set<string> SS;
typedef set<LL> SL;
typedef set<DB> SD;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef map<LL, int> MLI;
typedef map<DB, int> MDI;
typedef map<int, bool> MIB;
typedef map<string, bool> MSB;
typedef map<LL, bool> MLB;
typedef map<DB, bool> MDB;
typedef pair<int, int> PII;
typedef pair<int, bool> PIB;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;
typedef set<PII> SII;
typedef map<PII, int> MPIII;
typedef map<PII, bool> MPIIB;

/** I/O Accelerator **/

/* ... :" We are I/O Accelerator ... Use us at your own risk ;) ... " .. */

template<class T> inline void RD(T &);
template<class T> inline void OT(const T &);

template<class T> inline T& _RD(T &x){ RD(x); return x;}
inline int RD(){ int x; RD(x); return x;}
inline LL RD_LL(){ LL x; RD(x); return x;}
inline DB RD_DB(){ DB x; RD(x); return x;}

template<class T0, class T1> inline void RD(T0 &x0, T1 &x1){RD(x0), RD(x1);}
template<class T0, class T1, class T2> inline void RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2);}
template<class T0, class T1, class T2, class T3> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);}
template<class T0, class T1> inline void OT(T0 &x0, T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(T0 &x0, T1 &x1, T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T> inline void CLR(T &A){A.clear();}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2){FLC(A0), FLC(A1), FLC(A2);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3){FLC(A0), FLC(A1), FLC(A2), FLC(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5), FLC(A6);}

template<class T> inline void SRT(T &A){sort(ALL(A));}
template<class T, class C> inline void SRT(T &A, C B){sort(ALL(A), B);}

/** Add - On **/

const int MOD = 1000000007;
const int INF = 0x7fffffff;
const DB PI = acos(-1.0);
const DB EPS = 1e-6;
const DB OO = 1e15;

// <<= ` 0. Daily Use .,

template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
template<class T> inline void checkMax(T &a,const T b){if (b>a) a=b;}
template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
int Ceil(int x, int y){return (x - 1) / y + 1;}

// <<= ` 1. Bitwise Operation .,

inline bool _1(int x, int i){return x & 1<<i;}
inline int _1(int i){return 1<<i;}
inline int _U(int i){return _1(i) - 1;};

inline int count_bits(int x){
    x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
    x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
    x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
    x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
    x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
    return x;
}

template<class T> inline T low_bit(T x) {
    return x & -x;
}

template<class T> inline T high_bit(T x) {
    T p = low_bit(x);
    while (p != x) x -= p, p = low_bit(x);
    return p;
}

// <<= ` 2. Modular Arithmetic Basic .,

inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}
inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
inline int pdt(int a, int b){return (LL)a * b % MOD;}

// <<= ' 0. I/O interface .,

template<class T> inline void RD(T &x){
    //cin >> x;
    //scanf("%d", &x);
    char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
    //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';

}

int ____Case;
template<class T> inline void OT(const T &x){
    //cout << x << endl;
    //printf("%d\n", x);
    //printf("%.2lf\n", x);
    printf("Case %d: %d\n", ++____Case, x);
}

/* .................................................................................................................................. */

const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

const int N = 1001, L = 100001;

PII I[L]; char maze[N][N]; set<char> Res;
int n, m, l; char a; int b;

bool bfs(int x, int y){
    REP(i, l){
        DO_C(I[i].second){
            x = x + dx[I[i].first], y = y + dy[I[i].first] ;
            if (maze[x][y] == '#') return false;
        }
    }
    return true;
}

int main(){

    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    //ios::sync_with_stdio(false);

    //while (scanf("%d", &n) != EOF){

    RD(n, m); REP_2(i, j, n, m) scanf(" %c", &maze[i][j]);

    RD(l); REP(i, l){
        scanf(" %c", &a); I[i].first = a == 'E' ? 0 : a == 'S' ? 1 : a == 'W' ? 2 : 3;
        RD(I[i].second);
    }

    REP_2(x, y, n, m) if ('A' <= maze[x][y] && maze[x][y] <= 'Z'){
        if (bfs(x, y)) Res.insert(maze[x][y]);
    }

    if (Res.empty()){
        cout << "no solution" << endl;
    }
    else {
        For_each(it, Res) cout << *it;
        cout << endl;
    }

}


/** ` Micro Mezzo Macro Flation -- Overheated Economy ., **/

#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <bitset>
#include <list>
#include <set>
#include <map>
#include <queue>

using namespace std;

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)
#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)
#define DO(n) while(n--)
#define DO_C(n) int n____ = n; while(n____--)
#define TO(i, a, b) int s_=a<b?1:-1,b_=b+s_;for(int i=a;i!=b_;i+=s_)
#define TO_1(i, a, b) int s_=a<b?1:-1,b_=b;for(int i=a;i!=b_;i+=s_)
#define SQZ(i, j, a, b) for (int i=int(a),j=int(b)-1;i<j;++i,--j)
#define SQZ_1(i, j, a, b) for (int i=int(a),j=int(b);i<=j;++i,--j)
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define BSC(A, X) find(ALL(A), X) // != A.end()
#define CTN(T, x) T.find(x) != T.end()
#define SZ(A) int(A.size())
#define PB push_back
#define MP(A, B) make_pair(A, B)

#define Rush int T____; RD(T____); DO(T____)
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#define Ruby system("ruby main.rb")
#define Haskell system("runghc main.hs")
#define Pascal system("fpc main.pas")

typedef long long LL;
typedef double DB;
typedef unsigned UINT;
typedef unsigned long long ULL;

typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VD;
typedef set<int> SI;
typedef set<string> SS;
typedef set<LL> SL;
typedef set<DB> SD;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef map<LL, int> MLI;
typedef map<DB, int> MDI;
typedef map<int, bool> MIB;
typedef map<string, bool> MSB;
typedef map<LL, bool> MLB;
typedef map<DB, bool> MDB;
typedef pair<int, int> PII;
typedef pair<int, bool> PIB;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;
typedef set<PII> SII;
typedef map<PII, int> MPIII;
typedef map<PII, bool> MPIIB;

/** I/O Accelerator **/

/* ... :" We are I/O Accelerator ... Use us at your own risk ;) ... " .. */

template<class T> inline void RD(T &);
template<class T> inline void OT(const T &);

template<class T> inline T& _RD(T &x){ RD(x); return x;}
inline int RD(){ int x; RD(x); return x;}
inline LL RD_LL(){ LL x; RD(x); return x;}
inline DB RD_DB(){ DB x; RD(x); return x;}

template<class T0, class T1> inline void RD(T0 &x0, T1 &x1){RD(x0), RD(x1);}
template<class T0, class T1, class T2> inline void RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2);}
template<class T0, class T1, class T2, class T3> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6);}
template<class T0, class T1> inline void OT(T0 &x0, T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(T0 &x0, T1 &x1, T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T> inline void CLR(T &A){A.clear();}
template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2){FLC(A0), FLC(A1), FLC(A2);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3){FLC(A0), FLC(A1), FLC(A2), FLC(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){FLC(A0), FLC(A1), FLC(A2), FLC(A3), FLC(A4), FLC(A5), FLC(A6);}

template<class T> inline void SRT(T &A){sort(ALL(A));}
template<class T, class C> inline void SRT(T &A, C B){sort(ALL(A), B);}

/** Add - On **/

const int MOD = 1000000007;
const int INF = 0x7fffffff;
const DB PI = acos(-1.0);
const DB EPS = 1e-6;
const DB OO = 1e15;

// <<= ` 0. Daily Use .,

template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;}
template<class T> inline void checkMax(T &a,const T b){if (b>a) a=b;}
template <class T, class C> inline void checkMin(T& a, const T b, C c){if (c(b,a)) a = b;}
template <class T, class C> inline void checkMax(T& a, const T b, C c){if (c(a,b)) a = b;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
int Ceil(int x, int y){return (x - 1) / y + 1;}

// <<= ` 1. Bitwise Operation .,

inline bool _1(int x, int i){return x & 1<<i;}
inline int _1(int i){return 1<<i;}
inline int _U(int i){return _1(i) - 1;};

inline int count_bits(int x){
    x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1);
    x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2);
    x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4);
    x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8);
    x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);
    return x;
}

template<class T> inline T low_bit(T x) {
    return x & -x;
}

template<class T> inline T high_bit(T x) {
    T p = low_bit(x);
    while (p != x) x -= p, p = low_bit(x);
    return p;
}

// <<= ` 2. Modular Arithmetic Basic .,

inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}
inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
inline int pdt(int a, int b){return (LL)a * b % MOD;}

// <<= ' 0. I/O interface .,

template<class T> inline void RD(T &x){
    //cin >> x;
    //scanf("%d", &x);
    char c; for (c = getchar(); c < '0'; c = getchar()); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';
    //char c; c = getchar(); x = c - '0'; for (c = getchar(); c >= '0'; c = getchar()) x = x * 10 + c - '0';

}

int ____Case;
template<class T> inline void OT(const T &x){
    //cout << x << endl;
    //printf("%d\n", x);
    //printf("%.2lf\n", x);
    printf("Case %d: %d\n", ++____Case, x);
}

#define For_each(it, A) for (set<char>::iterator it = A.begin(); it != A.end(); ++it)
#define For_each_(it, A) for (SII::iterator it = A.begin(); it != A.end(); ++it)
/* .................................................................................................................................. */

const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
const int N = 1001, L = 100001;

SII S;
PII I[L]; char maze[N][N]; set<char> Res;
int n, m, l; char a; int b;

bool bfs(int x, int y){
    For_each_(it, S){
        int xx = x + it->first, yy = y + it->second ;
        if (xx < 0 || yy < 0 || xx >= n || yy >= m || maze[xx][yy] == '#') return false;
    }
    return true;
}

int main(){
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    //ios::sync_with_stdio(false);
    //while (scanf("%d", &n) != EOF){

    RD(n, m); REP_2(i, j, n, m) scanf(" %c", &maze[i][j]);

    int x = 0, y = 0, up = 0, bottom = 0, left = 0, right = 0;
    RD(l); REP(i, l){
        scanf(" %c", &a); I[i].first = a == 'E' ? 0 : a == 'S' ? 1 : a == 'W' ? 2 : 3;
        RD(I[i].second), x += dx[I[i].first] * I[i].second, y += dy[I[i].first] * I[i].second;
        checkMin(up, x), checkMax(bottom, x), checkMin(left, y), checkMax(right, y);
        S.insert(MP(x, y));
    }

    FOR(x, abs(up), n - bottom) FOR(y, abs(left), m - right) if ('A' <= maze[x][y] && maze[x][y] <= 'Z'){
        if (bfs(x, y)) Res.insert(maze[x][y]);
    }

    if (Res.empty()){
        cout << "no solution" << endl;
    }
    else {
        For_each(it, Res) cout << *it;
        cout << endl;
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>

using namespace std;

typedef struct {
	int i, j;
	char id;
} coord;

typedef struct {
	char dir;
	int qtd;
} comando;

char mapa[10001][1001];
vector<comando> comandos;

inline void proximo(coord *atual, comando &comand){
	switch(comand.dir){
	case 'N':
		atual->i--;
	break;
	case 'E':
		atual->j++;
	break;
	case 'S':
		atual->i++;
	break;
	case 'W':
		atual->j--;
	break;
	}
}

bool seguir_comandos(coord inicio){
	int num_comandos = comandos.size();
	for(int i = 0; i < num_comandos; i++){
		comando atual = comandos[i];

		for(int j = 0; j < atual.qtd; j++){
			proximo(&inicio, atual);
			if(mapa[inicio.i][inicio.j] == '#')
				return false;
		}
	}

	return true;
}

int main(){
	int lin, col;
	char pos_atual;
	vector<coord> locais;
	string linha;
	coord possivel;

	cin >> lin >> col;
	getchar();
	for(int i = 0; i < lin; i++){
		for(int j = 0; j < col; j++){
			pos_atual = getchar();
			mapa[i][j] = pos_atual;
			if(pos_atual >= 'A' && pos_atual <= 'Z'){
				possivel.i = i;
				possivel.j = j;
				possivel.id = pos_atual;
				locais.push_back(possivel);
			}
		}
		getchar();
	}

	int num_comandos;
	comando comand;
	cin >> num_comandos;

	for(int i = 0; i < num_comandos; i++){
		cin >> comand.dir >> comand.qtd;
		comandos.push_back(comand);
	}

	vector<char> respostas;

	int num_possiveis = locais.size();
	for(int i = 0; i < num_possiveis; i++){
		if(seguir_comandos(locais[i]))
			respostas.push_back(locais[i].id);
	}

	sort(respostas.begin(), respostas.end());

	int num_respostas = respostas.size();

	if(num_respostas == 0){
		cout << "no solution";
		return 0;
	}

	for(int i = 0; i < num_respostas; i++)
		cout << respostas[i];

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef struct {
	int i, j;
	char id;
} coord;

typedef struct {
	char dir;
	int qtd;
} comando;

vector<string> mapa;
vector<comando> comandos;

void proximo(coord *atual, comando comand){
	switch(comand.dir){
	case 'N':
		atual->i--;
	break;
	case 'E':
		atual->j++;
	break;
	case 'S':
		atual->i++;
	break;
	case 'W':
		atual->j--;
	break;
	}
}

bool seguir_comandos(coord inicio){
	int num_comandos = comandos.size();
	for(int i = 0; i < num_comandos; i++){
		comando atual = comandos[i];

		for(int j = 0; j < atual.qtd; j++){
			proximo(&inicio, atual);
			if(mapa[inicio.i][inicio.j] == '#')
				return false;
		}
	}

	return true;
}

int main(){
	int lin, col;
	vector<coord> locais;
	string linha;
	coord possivel;

	cin >> lin >> col;
	getline(cin, linha);
	for(int i = 0; i < lin; i++){
		getline(cin, linha);

		for(int j = 0; j < col; j++){
			if(linha[j] >= 'A' && linha[j] <= 'Z'){
				possivel.i = i;
				possivel.j = j;
				possivel.id = linha[j];
				locais.push_back(possivel);
			}
		}

		mapa.push_back(linha);
	}

	int num_comandos;
	comando comand;
	cin >> num_comandos;

	for(int i = 0; i < num_comandos; i++){
		cin >> comand.dir >> comand.qtd;
		comandos.push_back(comand);
	}

	vector<char> respostas;

	int num_possiveis = locais.size();
	for(int i = 0; i < num_possiveis; i++){
		if(seguir_comandos(locais[i]))
			respostas.push_back(locais[i].id);
	}

	sort(respostas.begin(), respostas.end());

	int num_respostas = respostas.size();

	if(num_respostas == 0){
		cout << "no solution";
		return 0;
	}

	for(int i = 0; i < num_respostas; i++)
		cout << respostas[i];

	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>

using namespace std;

typedef struct {
	int i, j;
	char id;
} coord;

typedef struct {
	char dir;
	int qtd;
} comando;

typedef struct {
	char conteudo;
	int ns_disp, ew_disp, sn_disp, we_disp;
} pos_mapa;

pos_mapa mapa[1001][1001];
int lin, col;
vector<comando> comandos;

inline bool proximo(coord *atual, comando &comand){
	if(comand.dir == 'N' && mapa[atual->i][atual->j].sn_disp >= comand.qtd){
		atual->i -= comand.qtd;
		return true;
	}

	if(comand.dir == 'E' && mapa[atual->i][atual->j].we_disp >= comand.qtd){
		atual->j += comand.qtd;
		return true;
	}

	if(comand.dir == 'S' && mapa[atual->i][atual->j].ns_disp >= comand.qtd){
		atual->i += comand.qtd;
		return true;
	}

	if(comand.dir == 'W' && mapa[atual->i][atual->j].ew_disp >= comand.qtd){
		atual->j -= comand.qtd;
		return true;
	}

	return false;
}

bool seguir_comandos(coord inicio){
	int num_comandos = comandos.size();
	for(int i = 0; i < num_comandos; i++){
		comando atual = comandos[i];

		if(!proximo(&inicio, atual)){
			return false;
		}
	}
	return true;
}

void pre_processar_mapa(){
	int disp;
	for(int i = 0; i < lin; i++){
		disp = 0;
		//Varrendo W->E
		for(int j = 0; j < col; j++){
			if(mapa[i][j].conteudo == '#'){
				disp = 0;
				continue;
			}
			mapa[i][j].ew_disp = disp;
			disp++;
		}

		disp = 0;
		//Varrendo E->W
		for(int j = col - 1; j >= 0; j--){
			if(mapa[i][j].conteudo == '#'){
				disp = 0;
				continue;
			}
			mapa[i][j].we_disp = disp;
			disp++;
		}
	}

	for(int j = 0; j < col; j++){
		disp = 0;
		//Varrendo N->S
		for(int i = 0; i < lin; i++){
			if(mapa[i][j].conteudo == '#'){
				disp = 0;
				continue;
			}
			mapa[i][j].sn_disp = disp;
			disp++;
		}

		disp = 0;
		//Varrendo S->N
		for(int i = lin - 1; i >= 0; i--){
			if(mapa[i][j].conteudo == '#'){
				disp = 0;
				continue;
			}
			mapa[i][j].ns_disp = disp;
			disp++;
		}
	}
}

int main(){
	vector<coord> locais;
	string linha;
	coord possivel;

	cin >> lin >> col;
	getchar();

	for(int i = 0; i < lin; i++){
		for(int j = 0; j < col; j++){
			mapa[i][j].conteudo = getchar();

			if(mapa[i][j].conteudo >= 'A' && mapa[i][j].conteudo <= 'Z'){
				possivel.i = i;
				possivel.j = j;
				possivel.id = mapa[i][j].conteudo;
				locais.push_back(possivel);
			}
		}
		getchar();
	}

	int num_comandos;
	comando comand;
	cin >> num_comandos;

	for(int i = 0; i < num_comandos; i++){
		cin >> comand.dir >> comand.qtd;
		comandos.push_back(comand);
	}

	pre_processar_mapa();

	vector<char> respostas;
	int num_possiveis = locais.size();
	for(int i = 0; i < num_possiveis; i++){
		if(seguir_comandos(locais[i]))
			respostas.push_back(locais[i].id);
	}

	sort(respostas.begin(), respostas.end());

	int num_respostas = respostas.size();

	if(num_respostas == 0){
		cout << "no solution";
		return 0;
	}

	for(int i = 0; i < num_respostas; i++)
		cout << respostas[i];

	return 0;
}


#include <iostream>
#include <cstdio>
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;

struct node
{
    int x, y;
    char c;
    node(int p, int q, char r): x(p), y(q), c(r){}
};

vector<node> sight;
vector<pair<char, int> > ins;
vector<char> ans;
int n, m, k;
char mp[1000][1000];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
        {
            cin >> mp[i][j];
            if(mp[i][j] != '#' && mp[i][j] != '.')
            {
                sight.push_back(node(i, j, mp[i][j]));
            }
        }
    scanf("%d", &k);
    for(int i = 0; i < k; i++)
    {
        char a;
        int b;
        cin >> a >> b;
        ins.push_back(make_pair(a, b));
    }
    for(int i = 0; i < sight.size(); i++)
    {
        bool ck = true;
        int x = sight[i].x, y =  sight[i].y;
        for(int j = 0; j < ins.size() && ck; j++)
        {
            if(ins[j].first == 'S')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    x++;
                    if(x >= n || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'N')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    x--;
                    if(x < 0 || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'E')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    y++;
                    if(y >= m || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'W')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    y--;
                    if(y < 0 || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
        }
        if(ck)
            ans.push_back(sight[i].c);
    }
    if(ans.size() > 0)
    {
        sort(ans.begin(), ans.end());
        for(int i = 0; i < ans.size(); i++)
            putchar(ans[i]);
        putchar('\n');
    }
    else
    {
        puts("no solution");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;

struct node
{
    int x, y;
    char c;
    node(int p, int q, char r): x(p), y(q), c(r){}
};

vector<node> sight;
vector<pair<char, int> > ins;
vector<char> ans;
int n, m, k;
char mp[1000][1000], s[1000];
int up[1000][1000], lt[1000][1000];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", s);
        for(int j = 0; j < m; j++)
        {
            mp[i][j] = s[j];
            if(j > 0 && mp[i][j - 1] != '#' && mp[i][j] != '#')
            {
                lt[i][j] = lt[i][j - 1] + 1;
            }
            if(i > 0 && mp[i - 1][j] != '#' && mp[i][j] != '#')
            {
                up[i][j] = up[i - 1][j] + 1;
            }
        }
    }
    scanf("%d", &k);
    for(int i = 0; i < k; i++)
    {
        char a;
        int b;
        cin >> a >> b;
        ins.push_back(make_pair(a, b));
    }
    string ans = "";
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
        {
            if(mp[i][j] >= 'A' && mp[i][j] <= 'Z')
            {
                int r = i, c = j;
                bool ck = true;
                for(int l = 0; l < ins.size(); l++)
                {
                    char dir = ins[l].first;
                    int dis = ins[l].second;
                    if(dir == 'N' && dis <= up[r][c])
                        r -= dis;
                    else if(dir == 'S' && r + dis < n && up[r + dis][c] >= dis)
                        r += dis;
                    else if(dir == 'W' && dis <= lt[r][c])
                        c -= dis;
                    else if(dir == 'E' && c + dis < m && lt[r][c + dis] >= dis)
                        c += dis;
                    else
                    {
                        ck=false;break;
                    }
                }
                if(ck)
                    ans += mp[i][j];
            }
        }
    sort(ans.begin(), ans.end());
    if(ans.size() > 0 )
        puts(ans.c_str());
    else
        puts("no solution");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;

struct node
{
    int x, y;
    char c;
    node(int p, int q, char r): x(p), y(q), c(r){}
};

vector<node> sight;
vector<pair<char, int> > ins;
vector<char> ans;
int n, m, k;
char mp[1000][1000], s[1000];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", s);
        for(int j = 0; j < m; j++)
        {
            mp[i][j] = s[j];
            if(mp[i][j] != '#' && mp[i][j] != '.')
            {
                sight.push_back(node(i, j, mp[i][j]));
            }
        }
    }
    scanf("%d", &k);
    for(int i = 0; i < k; i++)
    {
        char a;
        int b;
        cin >> a >> b;
        ins.push_back(make_pair(a, b));
    }
    for(int i = 0; i < sight.size(); i++)
    {
        bool ck = true;
        int x = sight[i].x, y =  sight[i].y;
        for(int j = 0; j < ins.size() && ck; j++)
        {
            if(ins[j].first == 'S')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    x++;
                    if(x >= n || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'N')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    x--;
                    if(x < 0 || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'E')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    y++;
                    if(y >= m || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
            else if(ins[j].first == 'W')
            {
                for(int l = 0; l < ins[j].second; l++)
                {
                    y--;
                    if(y < 0 || mp[x][y] == '#')
                    {
                        ck = false;
                        break;
                    }
                }
            }
        }
        if(ck)
            ans.push_back(sight[i].c);
    }
    if(ans.size() > 0)
    {
        sort(ans.begin(), ans.end());
        for(int i = 0; i < ans.size(); i++)
            putchar(ans[i]);
        putchar('\n');
    }
    else
    {
        puts("no solution");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;

struct node
{
    int x, y;
    char c;
    node(int p, int q, char r): x(p), y(q), c(r){}
};

vector<node> sight;
vector<pair<char, int> > ins;
vector<char> ans;
int n, m, k;
char mp[1000][1000], s[1000];
int up[1000][1000], lt[1000][1000];

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
    {
        scanf("%s", s);
        for(int j = 0; j < m; j++)
        {
            mp[i][j] = s[j];
            if(j > 0 && mp[i][j - 1] != '#')
            {
                lt[i][j] = lt[i][j - 1] + 1;
            }
            if(i > 0 && mp[i - 1][j] != '#')
            {
                up[i][j] = up[i - 1][j] + 1;
            }
        }
    }
    scanf("%d", &k);
    for(int i = 0; i < k; i++)
    {
        char a;
        int b;
        cin >> a >> b;
        ins.push_back(make_pair(a, b));
    }
    string ans = "";
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
        {
            if(mp[i][j] >= 'A' && mp[i][j] <= 'Z')
            {
                int r = i, c = j;
                bool ck = true;
                for(int l = 0; l < ins.size(); l++)
                {
                    char dir = ins[l].first;
                    int dis = ins[l].second;
                    if(dir == 'N' && dis <= up[r][c])
                        r -= dis;
                    else if(dir == 'S' && r + dis < n && up[r + dis][c] >= dis)
                        r += dis;
                    else if(dir == 'W' && dis <= lt[r][c])
                        c -= dis;
                    else if(dir == 'E' && c + dis < m && lt[r][c + dis] >= dis)
                        c += dis;
                    else
                    {
                        ck=false;break;
                    }
                }
                if(ck)
                    ans += mp[i][j];
            }
        }
    sort(ans.begin(), ans.end());
    if(ans.size() > 0 )
        puts(ans.c_str());
    else
        puts("no solution");
    return 0;
}


/*
Author : OmarEl-Mohandes
PROG   : A
LANG   : C++
*/
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <memory.h>
using namespace std;
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz size()
#define rep(i,m) for(int i=0;i<m;i++)
#define REP(i,k,m) for(int i=k;i<m;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define mp make_pair
typedef stringstream ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef  long long ll;
#define oo ((int)1e9)
int n , m;
char mat[1002][1002];
bool check(int x , int y){
    return x >= 0 && x < n && y >= 0 && y < m && (mat[x][y] != '#');
}
int main()
{
//  freopen("test.in" , "rt" , stdin);
    //freopen("A.out" , "wt" , stdout);
    map<char , pair<int , int> > M;
    map<char , pair<int , int> >dirs;
    dirs['N'] = mp(-1 , 0);
    dirs['S'] = mp(1 , 0);
    dirs['W'] = mp(0 , -1);
    dirs['E'] = mp(0 , 1);
    scanf("%d%d" , &n , &m);
    for(int i = 0 ; i < n ; i ++)
        for(int j = 0 ; j < m ; j ++)
        {
            scanf(" %c" , &mat[i][j]);
            if(isalpha(mat[i][j]))
                M[mat[i][j]] = mp(i , j);
        }
    int K;
    scanf("%d" , &K);
    vector<pair<char , int > > in(K);
    for(int i = 0 ; i < K ; i ++)
        scanf(" %c%d" , &in[i].first , &in[i].second);
    string res = "";
    for(map<char , pair<int , int> > :: iterator it = M.begin() ; it != M.end() ; it ++){
        int x = (*it).second.first;
        int y = (*it).second.second;
        int k = 0;
        while(k < K && check(x+=dirs[in[k].first].first*in[k].second , y += dirs[in[k].first].second*in[k].second))k++;
        if(k == K)
            res += (*it).first;
    }
    if(res.size() == 0)
        cout << "no solution" << endl;
    else
        cout << res << endl;
    return 0;
}


/*
Author : OmarEl-Mohandes
PROG   : A
LANG   : C++
*/
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <memory.h>
using namespace std;
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz size()
#define rep(i,m) for(int i=0;i<m;i++)
#define REP(i,k,m) for(int i=k;i<m;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define mp make_pair
typedef stringstream ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef  long long ll;
#define oo ((int)1e9)
int n , m;
int mat[1002][1002];
bool vis[1002][1002];
int maz[1002][1002][4];
map<char , pair<int , int> > M;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int rev[]={1,0,3,2};
string dirs = "NSWE";
void init()
{
	for(int i = 0 ; i < n ; i ++){
		for(int j = 0 ; j < m ; j ++){
			if(mat[i][j] == -2)
			{
				for(int d = 0 ; d < 4 ; d ++){
					int x = i+dx[d];
					int y = j+dy[d];
					int l = 0;
					while(1)
					{
						if(x >= 0 && y >= 0 && x < n && y < m && mat[x][y] != -2)
							maz[x][y][rev[d]] = l;
						else
							break;
						l ++;
						x += dx[d];
						y += dy[d];
					}
				}
			}
		}
	}
}
int main()
{
//	freopen("test.in" , "rt" , stdin);
	//freopen("A.out" , "wt" , stdout);
	scanf("%d%d" , &n , &m);
	char c;
	for(int i = 0 ; i < n ; i ++)
		for(int j = 0 ; j < m ; j ++)
		{
			scanf(" %c" , &c);
			if(isalpha(c))
				M[c] = mp(i , j);
			if(c == '#')
				mat[i][j] = -2;
		}
	init();
	int K;
	scanf("%d" , &K);
	vector<pair<char , int > > in(K);
	for(int i = 0 ; i < K ; i ++)
		scanf(" %c%d" , &in[i].first , &in[i].second);
	string res = "";
	for(map<char , pair<int , int> > :: iterator it = M.begin() ; it != M.end() ; it ++){
		int x = (*it).second.first;
		int y = (*it).second.second;
		bool f = 1;
		for(int i = 0 ; i < K ; i ++){
			int ind = dirs.find(in[i].first);
			if(maz[x][y][ind] >= in[i].second){
				x += dx[ind]*in[i].second;
				y += dy[ind]*in[i].second;
			}
			else
			{
				f = 0;
				break;
			}
		}
		if(f)
			res += (*it).first;
	}
	if(res.size() == 0)
		cout << "no solution" << endl;
	else
		cout << res << endl;
	return 0;
}


/*
Author : OmarEl-Mohandes
PROG   : A
LANG   : C++
*/
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <memory.h>
using namespace std;
#define pb push_back
#define all(v) v.begin(),v.end()
#define sz size()
#define rep(i,m) for(int i=0;i<m;i++)
#define REP(i,k,m) for(int i=k;i<m;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#define mp make_pair
typedef stringstream ss;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<vector<int> > vii;
typedef  long long ll;
#define oo ((int)1e9)
int n , m;
char mat[1002][1002];
map<char , pair<int , int> > M;
map<char , pair<int , int> >dirs;
bool check(int x1 , int y1 , int d , char c){

	for(int i = 0 ; i <= d ; i ++){
		if(!(x1 >= 0 && x1 < n && y1 >= 0 && y1 < m && mat[x1][y1] != '#'))return 0;
		x1 += dirs[c].first;
		y1 += dirs[c].second;
	}
	return 1;
}
int main()
{
//	freopen("test.in" , "rt" , stdin);
	//freopen("A.out" , "wt" , stdout);
	dirs['N'] = mp(-1 , 0);
	dirs['S'] = mp(1 , 0);
	dirs['W'] = mp(0 , -1);
	dirs['E'] = mp(0 , 1);
	scanf("%d%d" , &n , &m);
	for(int i = 0 ; i < n ; i ++)
		for(int j = 0 ; j < m ; j ++)
		{
			scanf(" %c" , &mat[i][j]);
			if(isalpha(mat[i][j]))
				M[mat[i][j]] = mp(i , j);
		}
	int K;
	scanf("%d" , &K);
	vector<pair<char , int > > in(K);
	for(int i = 0 ; i < K ; i ++)
		scanf(" %c%d" , &in[i].first , &in[i].second);
	string res = "";
	for(map<char , pair<int , int> > :: iterator it = M.begin() ; it != M.end() ; it ++){
		int x = (*it).second.first;
		int y = (*it).second.second;
		int k = 0;
		while(k < K && check(x , y  , in[k].second , in[k].first))
		{
			x+=dirs[in[k].first].first*in[k].second , y += dirs[in[k].first].second*in[k].second , k++;

		}
		if(k == K)
			res += (*it).first;
	}
	if(res.size() == 0)
		cout << "no solution" << endl;
	else
		cout << res << endl;
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
char matrix[1010][1010];
struct dddd{
    char c[10];
    int d;
}e[100010];
struct point{
    int x,y;
}p[110],now;
char ans[110];
int len,n,m;
bool check(point x)
{
    if(x.x < 0||x.y < 0||x.x >= n||x.y >= m)
        return false;
    return true;
}
int main()
{
    int cnt = 0;
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        scanf("%s",matrix[i]);
        for(int j = 0; j < m; ++j){
            if(matrix[i][j] >= 'A'&&matrix[i][j] <= 'Z'){
                p[cnt].x = i,p[cnt].y = j;
                ++cnt;
            }
        }
    }
    int k;
    scanf("%d",&k);
    for(int i = 0; i < k; ++i)
        scanf("%s %d",e[i].c,&e[i].d);
    len = 0;
    for(int i = 0; i < cnt; ++i){
        now = p[i];
        bool fg = true;
        for(int j = 0; j < k; ++j){
            if(e[j].c[0] == 'N'){
                now.x -= e[j].d;
            }
            else if(e[j].c[0] == 'S'){
                now.x += e[j].d;
            }
            else if(e[j].c[0] == 'E'){
                now.y += e[j].d;
            }
            else if(e[j].c[0] == 'W'){
                now.y -= e[j].d;
            }
            if(check(now)==false){
                fg = false;
                break;
            }
        }
        if(fg){
            bool flag = true;
            now = p[i];
            for(int j = 0; j < k; ++j){
                if(e[j].c[0] == 'N'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.x;
                        if(matrix[now.x][now.y] == '#'){
                            flag = false;
                            break;
                        }
                    }
                }
                else if(e[j].c[0] == 'S'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.x;
                        if(matrix[now.x][now.y] == '#'){
                            flag = false;
                            break;
                        }
                    }
                }
                else if(e[j].c[0] == 'E'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.y;
                        if(matrix[now.x][now.y] == '#'){
                            flag = false;
                            break;
                        }
                    }
                }
                else if(e[j].c[0] == 'W'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.y;
                        if(matrix[now.x][now.y] == '#'){
                            flag = false;
                            break;
                        }
                    }
                }
                if(flag == false)
                    break;
            }
            if(flag)
                ans[len++] = matrix[p[i].x][p[i].y];
        }
    }
    if(len == 0){
        puts("no solution");
        return 0;
    }
    sort(ans,ans+len);
    ans[len] = 0;
    printf("%s\n",ans);
    return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
char matrix[1010][1010];
struct dddd{
    char c[10];
    int d;
}e[100010];
struct point{
    int x,y;
}p[110],now;
char ans[110];
int len,n,m;
bool check(point x)
{
    if(x.x < 0||x.y < 0||x.x >= n||x.y >= m)
        return false;
    return true;
}
int main()
{
    int cnt = 0;
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        scanf("%s",matrix[i]);
        for(int j = 0; j < m; ++j){
            if(matrix[i][j] >= 'A'&&matrix[i][j] <= 'Z'){
                p[cnt].x = i,p[cnt].y = j;
                ++cnt;
            }
        }
    }
    int k;
    scanf("%d",&k);
    for(int i = 0; i < k; ++i)
        scanf("%s %d",e[i].c,&e[i].d);
    len = 0;
    for(int i = 0; i < cnt; ++i){
        now = p[i];
        bool fg = true;
        for(int j = 0; j < k; ++j){
            if(e[j].c[0] == 'N'){
                now.x -= e[j].d;
            }
            else if(e[j].c[0] == 'S'){
                now.x += e[j].d;
            }
            else if(e[j].c[0] == 'E'){
                now.y += e[j].d;
            }
            else if(e[j].c[0] == 'W'){
                now.y -= e[j].d;
            }
            if(check(now)==false){
                fg = false;
                break;
            }
        }
        if(fg&&matrix[now.x][now.y]!='#'){
            ans[len++] = matrix[p[i].x][p[i].y];
        }
    }
    if(len == 0){
        puts("no solution");
        return 0;
    }
    sort(ans,ans+len);
    ans[len] = 0;
    printf("%s\n",ans);
    return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
char matrix[1010][1010];
bool mat[4010][4010];
struct dddd{
    char c[10];
    int d;
}e[100010];
struct point{
    int x,y;
}p[110],now;
char ans[110];
int len,n,m;
bool check(point x)
{
    if(x.x < 0||x.y < 0||x.x >= n||x.y >= m)
        return false;
    return true;
}
int main()
{
    int cnt = 0;
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        scanf("%s",matrix[i]);
        for(int j = 0; j < m; ++j){
            if(matrix[i][j] >= 'A'&&matrix[i][j] <= 'Z'){
                p[cnt].x = i,p[cnt].y = j;
                ++cnt;
            }
        }
    }
    int k;
    scanf("%d",&k);
    for(int i = 0; i < k; ++i)
        scanf("%s %d",e[i].c,&e[i].d);
    len = 0;
    bool call = true;
    for(int i = 0; i < cnt; ++i){
        now = p[i];
        bool fg = true;
        for(int j = 0; j < k; ++j){
            if(e[j].c[0] == 'N'){
                now.x -= e[j].d;
            }
            else if(e[j].c[0] == 'S'){
                now.x += e[j].d;
            }
            else if(e[j].c[0] == 'E'){
                now.y += e[j].d;
            }
            else if(e[j].c[0] == 'W'){
                now.y -= e[j].d;
            }
            if(check(now)==false){
                fg = false;
                break;
            }
        }
        if(fg){
            if(call){

        //Ԥ����
            now.x = 1000,now.y = 1000;
            mat[1000][1000] = true;
            for(int j = 0; j < k; ++j){
                if(e[j].c[0] == 'N'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.x;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'S'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.x;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'E'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.y;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'W'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.y;
                        mat[now.x][now.y] = true;
                    }
                }
            }
            call = false;
            //
            }
            bool flag = true;
            now = p[i];
            int x = 1000-now.x,y = 1000-now.y;
            for(int ii = 0; ii < n; ++ii){
                for(int jj = 0; jj < m; ++jj){
                    if(mat[x+ii][y+jj] == true&&matrix[ii][jj] == '#'){
                        flag = false;
                        break;
                    }
                }
                if(flag == false)
                    break;
            }
            if(flag)
                ans[len++] = matrix[p[i].x][p[i].y];
        }
    }
    if(len == 0){
        puts("no solution");
        return 0;
    }
    sort(ans,ans+len);
    ans[len] = 0;
    printf("%s\n",ans);
    return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;
char matrix[1010][1010];
bool mat[2010][2010];
struct dddd{
    char c[10];
    int d;
}e[100010];
struct point{
    int x,y;
}p[110],now;
char ans[110];
int len,n,m;
bool check(point x)
{
    if(x.x < 0||x.y < 0||x.x >= n||x.y >= m)
        return false;
    return true;
}
int main()
{
    int cnt = 0;
    scanf("%d%d",&n,&m);
    for(int i = 0; i < n; ++i){
        scanf("%s",matrix[i]);
        for(int j = 0; j < m; ++j){
            if(matrix[i][j] >= 'A'&&matrix[i][j] <= 'Z'){
                p[cnt].x = i,p[cnt].y = j;
                ++cnt;
            }
        }
    }
    int k;
    scanf("%d",&k);
    for(int i = 0; i < k; ++i)
        scanf("%s %d",e[i].c,&e[i].d);
    len = 0;
        //Ԥ����
            now.x = 1000,now.y = 1000;
            mat[1000][1000] = true;
            for(int j = 0; j < k; ++j){
                if(e[j].c[0] == 'N'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.x;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'S'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.x;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'E'){
                    for(int x = 0; x < e[j].d; ++x){
                        ++now.y;
                        mat[now.x][now.y] = true;
                    }
                }
                else if(e[j].c[0] == 'W'){
                    for(int x = 0; x < e[j].d; ++x){
                        --now.y;
                        mat[now.x][now.y] = true;
                    }
                }
            }
            //
    for(int i = 0; i < cnt; ++i){
        now = p[i];
        bool fg = true;
        for(int j = 0; j < k; ++j){
            if(e[j].c[0] == 'N'){
                now.x -= e[j].d;
            }
            else if(e[j].c[0] == 'S'){
                now.x += e[j].d;
            }
            else if(e[j].c[0] == 'E'){
                now.y += e[j].d;
            }
            else if(e[j].c[0] == 'W'){
                now.y -= e[j].d;
            }
            if(check(now)==false){
                fg = false;
                break;
            }
        }
        if(fg){
            bool flag = true;
            now = p[i];
            int x = 1000-now.x,y = 1000-now.y;
            for(int ii = 0; ii < n; ++ii){
                for(int jj = 0; jj < m; ++jj){
                    if(mat[x+ii][y+jj] == true&&matrix[ii][jj] == '#'){
                        flag = false;
                        break;
                    }
                }
                if(flag == false)
                    break;
            }
            if(flag)
                ans[len++] = matrix[p[i].x][p[i].y];
        }
    }
    if(len == 0){
        puts("no solution");
        return 0;
    }
    sort(ans,ans+len);
    ans[len] = 0;
    printf("%s\n",ans);
    return 0;
}