#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					for(int k=0; k<4; k++)
					{
						//cout<<M[i][j]<<" "<<k<<endl;

						int I = i, J = j, ok = 1;
						for(int u=0; u<n; u++)
						{
							int d = (D[u] + k) % 4;
							int L = K[u];

							if(L <= maxD(I, J, d) - 1)
							{
								I += L*dx[d];
								J += L*dy[d];
								//cout<<M[i][j]<<" "<<I<<" "<<J<<endl;
							}
							else
							{
								ok = 0;
								break;
							}
						}
						if(ok) x += M[i][j];
					}
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					for(int k=0; k<4; k++)
					{
						//cout<<M[i][j]<<" "<<k<<endl;

						int I = i, J = j, ok = 1;
						for(int u=0; u<n; u++)
						{
							int d = (D[u] + k) % 4;
							int L = K[u];

							if(L <= maxD(I, J, d) - 1)
							{
								I += L*dx[d];
								J += L*dy[d];
								//cout<<M[i][j]<<" "<<I<<" "<<J<<endl;
							}
							else
							{
								ok = 0;
								break;
							}
						}
						if(ok)
						{
							x += M[i][j];
							break;
						}
					}
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					for(int k=0; k<1; k++)
					{
						//cout<<M[i][j]<<" "<<k<<endl;

						int I = i, J = j, ok = 1;
						for(int u=0; u<n; u++)
						{
							int d = (D[u] + k) % 4;
							int L = K[u];

							if(L <= maxD(I, J, d) - 1)
							{
								I += L*dx[d];
								J += L*dy[d];
								//cout<<M[i][j]<<" "<<I<<" "<<J<<endl;
							}
							else
							{
								ok = 0;
								break;
							}
						}
						if(ok)
						{
							x += M[i][j];
							break;
						}
					}
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					for(int k=0; k<4; k++)
					{
						//cout<<M[i][j]<<" "<<k<<endl;

						int I = i, J = j, ok = 1;
						for(int u=n-1; u>=0; u--)
						{
							int d = (D[u] + k) % 4;
							int L = K[u];

							if(L <= maxD(I, J, d) - 1)
							{
								I += L*dx[d];
								J += L*dy[d];
								//cout<<M[i][j]<<" "<<I<<" "<<J<<endl;
							}
							else
							{
								ok = 0;
								break;
							}
						}
						if(ok) x += M[i][j];
					}
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					int I = i, J = j, ok = 1;
					for(int u=0; u<n; u++)
					{
						if(K[u] <= maxD(I, J, D[u]) - 1)
						{
							I += K[u]*dx[D[u]];
							J += K[u]*dy[D[u]];
						}
						else
						{
							ok = 0;
							break;
						}
					}
					if(ok) x += M[i][j];
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>

using namespace std;

int R, C;

vector <string> M;

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

int f(string s)
{
	if(s=="N") return 0;
	else if(s=="E") return 1;
	else if(s=="S") return 2;
	else return 3;
}

int memo[1005][1005][4];

int maxD(int i, int j, int d)
{
	if(i < 0 || i >= R || j < 0 || j >= C || M[i][j] == '#') return 0;

	else if(memo[i][j][d] != -1) return memo[i][j][d];

	else return memo[i][j][d] = 1 + maxD(i + dx[d], j + dy[d], d);
}

int main()
{
	while(cin>>R>>C)
	{
		M = vector <string> (R);

		for(int i=0; i<R; i++)
			cin>>M[i];

		memset(memo, -1, sizeof(memo));

		int n;
		cin>>n;

		int D[n], K[n];

		for(int i=0; i<n; i++)
		{
			string s;
			cin>>s>>K[i];
			D[i] = f(s);
		}

		string x = "";

		for(int i=0; i<R; i++)
		{
			for(int j=0; j<C; j++)
			{
				if(M[i][j] >= 'A' && M[i][j] <= 'Z')
				{
					int I = i, J = j, ok = 1;
					for(int u=0; u<n; u++)
					{
						if(K[u] <= maxD(I, J, D[u]) - 1)
						{
							I += K[u]*dx[d];
							J += K[u]*dy[d];
						}
						else
						{
							ok = 0;
							break;
						}
					}
					if(ok) x += M[i][j];
				}
			}
		}

		sort(x.begin(), x.end());
		if(x != "") cout<<x<<endl;
		else cout<<"no solution"<<endl;
	}

	return 0;
}


/*
 *
 *	File Name:div2d
 *	Author: parth_sandeep
 *	Difficulty:
 *	Description:
 *
 *       believe in your fucking self.
 */

#include <bits/stdc++.h>
#define lli long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define sz size
using namespace std;
typedef vector<int> VII;
typedef pair <int, int> PII;
typedef vector<pair<int, int> >VPII;
const int MOD = 1e9 + 7;
const int MAX = 1111;
lli l[MAX][MAX];
lli r[MAX][MAX];
lli u[MAX][MAX];
lli d[MAX][MAX];
lli dis[2*MAX];
char dir[2*MAX][2];
lli n,m,k;
char s[MAX][MAX];
bool ok(lli x,lli y)
{
	lli i;
	for(i=0;i<k && 0<=x && x<n && 0<=y && y<m;++i)
	{
		if(dir[i][0]=='N')
		{
			if(u[x][y]-1<dis[i])
               return false;
             x-=dis[i];
		}
		else if(dir[i][0]=='S')
		{
			if(d[x][y]-1<dis[i])
				return false;
			x+=dis[i];
		}
		else if(dir[i][0]=='W')
		{
			if(l[x][y]-1<dis[i])
				return false;
			y-=dis[i];
		}
		else
		{
			if(r[x][y]-1<dis[i])
				return false;
			   y+=dis[i];
		}
	}
	return true;
}
int main(int argc, char* argv[])
{
ios_base::sync_with_stdio(0);
cin>>n>>m;
lli i,j;
for(i=0;i<n;++i)
	cin>>s[i];
for(i=0;i<n;++i)
{
	l[i][0]=s[i][0]!='#';
	for(j=1;j<m;++j)
	{
		if(s[i][j]!='#')
			l[i][j]=l[i][j-1]+1;
	}
	r[i][m-1]=s[i][m-1]!='#';
	for(j=m-2;j>=0;--j)
	{
		if(s[i][j]!='#')
			r[i][j]=r[i][j+1]+1;
	}
}
for(j=0;j<m;++j)
{
	u[0][j]=s[0][j]!='#';
	for(i=1;i<n;++i)
	{
		if(s[i][j]!='#')
			u[i][j]=u[i-1][j]+1;
	}
	u[n-1][j]=s[n-1][j]!='#';
	for(i=n-2;i>=0;--i)
	{
		if(s[i][j]!='#')
			d[i][j]=d[i+1][j]+1;
	}
}
cin>>k;
for(i=0;i<k;++i)
	cin>>dir[i]>>dis[i];
string o;
for(i=0;i<n;++i)
{
	for(j=0;j<m;++j)
	{
		if(isupper(s[i][j]))
		{
			if(ok(i,j))
				o.push_back(s[i][j]);
		}
	}
}
sort(o.begin(),o.end());
cout<<(o.empty()?"no solution":o);
return 0;
}


/*
 *
 *	File Name:div2d
 *	Author: parth_sandeep
 *	Difficulty:
 *	Description:
 *
 *       believe in your fucking self.
 */

#include <bits/stdc++.h>
#define lli long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define sz size
using namespace std;
typedef vector<int> VII;
typedef pair <int, int> PII;
typedef vector<pair<int, int> >VPII;
const int MOD = 1e9 + 7;
const int MAX = 1111;
lli l[MAX][MAX];
lli r[MAX][MAX];
lli u[MAX][MAX];
lli d[MAX][MAX];
lli dis[100*MAX];
char dir[100*MAX][2];
lli n,m,k;
char s[MAX][MAX];
bool ok(lli x,lli y)
{
	lli i;
	for(i=0;i<k && 0<=x && x<n && 0<=y && y<m;++i)
	{
		if(dir[i][0]=='N')
		{
			if(u[x][y]-1<dis[i])
               return false;
             x-=dis[i];
		}
		else if(dir[i][0]=='S')
		{
			if(d[x][y]-1<dis[i])
				return false;
			x+=dis[i];
		}
		else if(dir[i][0]=='W')
		{
			if(l[x][y]-1<dis[i])
				return false;
			y-=dis[i];
		}
		else
		{
			if(r[x][y]-1<dis[i])
				return false;
			   y+=dis[i];
		}
	}
	return true;
}
int main(int argc, char* argv[])
{
ios_base::sync_with_stdio(0);
cin>>n>>m;
lli i,j;
for(i=0;i<n;++i)
	cin>>s[i];
for(i=0;i<n;++i)
{
	l[i][0]=s[i][0]!='#';
	for(j=1;j<m;++j)
	{
		if(s[i][j]!='#')
			l[i][j]=l[i][j-1]+1;
	}
	r[i][m-1]=s[i][m-1]!='#';
	for(j=m-2;j>=0;--j)
	{
		if(s[i][j]!='#')
			r[i][j]=r[i][j+1]+1;
	}
}
for(j=0;j<m;++j)
{
	u[0][j]=s[0][j]!='#';
	for(i=1;i<n;++i)
	{
		if(s[i][j]!='#')
			u[i][j]=u[i-1][j]+1;
	}
	u[n-1][j]=s[n-1][j]!='#';
	for(i=n-2;i>=0;--i)
	{
		if(s[i][j]!='#')
			d[i][j]=d[i+1][j]+1;
	}
}
cin>>k;
for(i=0;i<k;++i)
	cin>>dir[i]>>dis[i];
string o;
for(i=0;i<n;++i)
{
	for(j=0;j<m;++j)
	{
		if(isupper(s[i][j]))
		{
			if(ok(i,j))
				o.push_back(s[i][j]);
		}
	}
}
sort(o.begin(),o.end());
cout<<(o.empty()?"no solution":o);
return 0;
}


/*
 *
 *	File Name:div2d
 *	Author: parth_sandeep
 *	Difficulty:
 *	Description:
 *
 *       believe in your fucking self.
 */

#include <bits/stdc++.h>
#define lli long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define sz size
using namespace std;
typedef vector<int> VII;
typedef pair <int, int> PII;
typedef vector<pair<int, int> >VPII;
const int MOD = 1e9 + 7;
const int MAX = 1111;
lli l[MAX][MAX];
lli r[MAX][MAX];
lli u[MAX][MAX];
lli d[MAX][MAX];
lli dis[2*MAX];
char dir[2*MAX][2];
lli n,m,k;
char s[MAX][MAX];
bool ok(lli x,lli y)
{
	lli i;
	for(i=0;i<k && 0<=x && x<n && 0<=y && y<m;++i)
	{
		if(dir[i][0]=='N')
		{
			if(u[x][y]-1<dis[i])
               return false;
             x-=dis[i];
		}
		else if(dir[i][0]=='S')
		{
			if(d[x][y]-1<dis[i])
				return false;
			x+=dis[i];
		}
		else if(dir[i][0]=='W')
		{
			if(l[x][y]-1<dis[i])
				return false;
			y-=dis[i];
		}
		else
		{
			if(r[x][y]-1<dis[i])
				return false;
			   y+=dis[i];
		}
	}
	return true;
}
int main(int argc, char* argv[])
{
ios_base::sync_with_stdio(0);
cin>>n>>m;
lli i,j;
for(i=0;i<n;++i)
	cin>>s[i];
for(i=0;i<n;++i)
{
	l[i][0]=s[i][0]!='#';
	for(j=1;j<m;++j)
	{
		if(s[i][j]!='#')
			l[i][j]=l[i][j-1]+1;
	}
	r[i][m-1]=s[i][m-1]!='#';
	for(j=m-2;j>=0;--j)
	{
		if(s[i][j]!='#')
			r[i][j]=r[i][j+1]+1;
	}
}
for(j=0;j<m;++j)
{
	u[0][j]=s[0][j]!='#';
	for(i=0;i<n;++i)
	{
		if(s[i][j]!='#')
			u[i][j]=u[i-1][j]+1;
	}
	u[n-1][j]=s[n-1][j]!='#';
	for(i=n-2;i>=0;--i)
	{
		if(s[i][j]!='#')
			d[i][j]=d[i+1][j]+1;
	}
}
cin>>k;
for(i=0;i<k;++i)
	cin>>dir[i]>>dis[i];
string o;
for(i=0;i<n;++i)
{
	for(j=0;j<m;++j)
	{
		if(isupper(s[i][j]))
		{
			if(ok(i,j))
				o.push_back(s[i][j]);
		}
	}
}
sort(o.begin(),o.end());
cout<<(o.empty()?"no solution":o);
return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;
	int j;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		if (*y - len < 0)
			return 1;
		for (j = 1; j <= len; j++)
			if (map[*y - j][*x] == '#')
				return 1;
		*y -= len;
		break;
	case 'S':
		if (*y + len >= n)
			return 1;
		for (j = 1; j <= len; j++)
			if (map[*y + j][*x] == '#')
				return 1;
		*y += len;
		break;
	case 'W':
		if (*x - len < 0)
			return 1;
		for (j = 1; j <= len; j++)
			if (map[*y][*x - j] == '#')
				return 1;
		*x -= len;
		break;
	case 'E':
		if (*x + len >= m)
			return 1;
		for (j = 1; j <= len; j++)
			if (map[*y][*x + j] == '#')
				return 1;
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++) {
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024
#define NORTH 0
#define SOUTH 1
#define WEST 2
#define EAST 3

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];
int safeDistance[MAX][MAX][4];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;
	int j;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		if (safeDistance[*y][*x][NORTH] < len)
			return 1;
		for (j = 1; j <= len; j++) {
			if (map[*y - j][*x] == '#') {
				safeDistance[*y][*x][NORTH] = j - 1;
				return 1;
			}
		}
		*y -= len;
		break;
	case 'S':
		if (safeDistance[*y][*x][SOUTH] < len)
			return 1;
		for (j = 1; j <= len; j++) {
			if (map[*y + j][*x] == '#') {
				safeDistance[*y][*x][SOUTH] = j - 1;
				return 1;
			}
		}
		*y += len;
		break;
	case 'W':
		if (safeDistance[*y][*x][WEST] < len)
			return 1;
		for (j = 1; j <= len; j++) {
			if (map[*y][*x - j] == '#') {
				safeDistance[*y][*x][WEST] = j - 1;
				return 1;
			}
		}
		*x -= len;
		break;
	case 'E':
		if (safeDistance[*y][*x][EAST] < len)
			return 1;
		for (j = 1; j <= len; j++) {
			if (map[*y][*x + j] == '#') {
				safeDistance[*y][*x][EAST] = j - 1;
				return 1;
			}
		}
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++) {
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

void inicializeSafeDistances (int rows, int cols) {
	int r, c;

	for (r = 0; r < rows; r++) {
		for (c = 0; c < cols; c++) {
			safeDistance[r][c][NORTH] = r;
			safeDistance[r][c][SOUTH] = rows - 1 - r;
			safeDistance[r][c][WEST] = c;
			safeDistance[r][c][EAST] = cols - 1 - c;
		}
	}
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	inicializeSafeDistances(rows, cols);

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>

#define MAX 1000
#define X 0
#define Y 1

struct instruction {
	char dir;
	int len;
};

char map[MAX][MAX];
int sights[32][2];
struct instruction instructions[100000];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;
	int j;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		for (j = 1; j <= len; j++)
			if (*y - j < 0 || map[*y - j][*x] == '#')
				return 1;
		*y -= len;
		break;
	case 'S':
		for (j = 1; j <= len; j++)
			if (*y + j >= n || map[*y + j][*x] == '#')
				return 1;
		*y += len;
		break;
	case 'W':
		for (j = 1; j <= len; j++)
			if (*x - j < 0 || map[*y][*x - j] == '#')
				return 1;
		*x -= len;
		break;
	case 'E':
		for (j = 1; j <= len; j++)
			if (*x + j >= m || map[*y][*x + j] == '#')
				return 1;
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight][X]; y = sights[numSight][Y];

	for (i = 0; i < numInstrs; i++) {
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;
	}
	return 1;
}

void bubbleSort(int numSights) {
	int swap, i, n;
	int xAux, yAux;

	n = numSights;
	do {
		swap = 0;
		for (i = 1; i < numSights; i++) {
			if (map[sights[i - 1][X]][sights[i - 1][Y]] > map[sights[i][X]][sights[i][Y]]) {
				swap = 1;
				xAux = sights[i - 1][X]; yAux = sights[i - 1][Y];
				sights[i - 1][X] = sights[i][X]; sights[i - 1][Y] = sights[i][Y];
				sights[i][X] = xAux; sights[i][Y] = yAux;
			}
		}
		n--;
	} while (swap == 1);
}

int main(int argc, char **argv) {
	int n, m, i, j, k;
	int valid; char dir; int len;
	int numSights = 0;

	scanf("%d %d\n", &n, &m);

	for (i = 0; i < n; i++) {
		fgets (map[i], MAX, stdin);

		for (j = 0; j < m; j++) {
			if (map[i][j] != '#' && map[i][j] != '.') {
				sights[numSights][Y] = i;
				sights[numSights][X] = j;
				numSights++;
			}
		}
	}

	bubbleSort(numSights);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, m, n, k)) {
			printf("%c", map[sights[i][Y]][sights[i][X]]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024
#define NORTH 0
#define SOUTH 1
#define WEST 2
#define EAST 3

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];
short safeDistance[MAX][MAX][4];

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y, j;
	char dir; int len;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++) {
		dir = instructions[i].dir;
		len = instructions[i].len;

		switch(dir) {
		case 'N':
			if (safeDistance[y][x][NORTH] < len)
				return 0;
			for (j = 1; j <= len; j++) {
				if (map[y - j][x] == '#') {
					safeDistance[y][x][NORTH] = j - 1;
					return 0;
				}
			}
			y -= len;
			break;
		case 'S':
			if (safeDistance[y][x][SOUTH] < len)
				return 0;
			for (j = 1; j <= len; j++) {
				if (map[y + j][x] == '#') {
					safeDistance[y][x][SOUTH] = j - 1;
					return 0;
				}
			}
			y += len;
			break;
		case 'W':
			if (safeDistance[y][x][WEST] < len)
				return 0;
			for (j = 1; j <= len; j++) {
				if (map[y][x - j] == '#') {
					safeDistance[y][x][WEST] = j - 1;
					return 0;
				}
			}
			x -= len;
			break;
		case 'E':
			if (safeDistance[y][x][EAST] < len)
				return 0;
			for (j = 1; j <= len; j++) {
				if (map[y][x + j] == '#') {
					safeDistance[y][x][EAST] = j - 1;
					return 0;
				}
			}
			x += len;
			break;
		}
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

void inicializeSafeDistances (int rows, int cols) {
	int r, c;

	for (r = 0; r < rows; r++) {
		for (c = 0; c < cols; c++) {
			safeDistance[r][c][NORTH] = r;
			safeDistance[r][c][SOUTH] = rows - 1 - r;
			safeDistance[r][c][WEST] = c;
			safeDistance[r][c][EAST] = cols - 1 - c;
		}
	}
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	inicializeSafeDistances(rows, cols);

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;
	int j;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		for (j = 1; j <= len; j++)
			if (*y - j < 0 || map[*y - j][*x] == '#')
				return 1;
		*y -= len;
		break;
	case 'S':
		for (j = 1; j <= len; j++)
			if (*y + j >= n || map[*y + j][*x] == '#')
				return 1;
		*y += len;
		break;
	case 'W':
		for (j = 1; j <= len; j++)
			if (*x - j < 0 || map[*y][*x - j] == '#')
				return 1;
		*x -= len;
		break;
	case 'E':
		for (j = 1; j <= len; j++)
			if (*x + j >= m || map[*y][*x + j] == '#')
				return 1;
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++) {
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024
#define NORTH 0
#define SOUTH 1
#define WEST 2
#define EAST 3

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];
int safeDistances[MAX][MAX][4];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		if (safeDistances[*y][*x][NORTH] < len)
			return 1;
		*y -= len;
		break;
	case 'S':
		if (safeDistances[*y][*x][SOUTH] < len)
			return 1;
		*y += len;
		break;
	case 'W':
		if (safeDistances[*y][*x][WEST] < len)
			return 1;
		*x -= len;
		break;
	case 'E':
		if (safeDistances[*y][*x][EAST] < len)
			return 1;
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++)
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;

	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

void calculateSafeDistance (int row, int col, int rows, int cols) {
	int distanceToBorder, safeDistance;
	int direction, i;
	if (map[row][col] == '#')
		return;

	for (direction = 0; direction < 4; direction++) {
		switch (direction) {
		case NORTH:
			distanceToBorder = row;
			safeDistance = distanceToBorder;
			for (i = 1; i <= distanceToBorder; i++) {
				if (map[row - i][col] == '#') {
					safeDistance = i - 1;
					break;
				}
			}
			safeDistances[row][col][NORTH] = safeDistance;
			break;
		case SOUTH:
			distanceToBorder = rows - 1 - row;
			safeDistance = distanceToBorder;
			for (i = 1; i <= distanceToBorder; i++) {
				if (map[row + i][col] == '#') {
					safeDistance = i - 1;
					break;
				}
			}
			safeDistances[row][col][SOUTH] = safeDistance;
			break;
		case WEST:
			distanceToBorder = col;
			safeDistance = distanceToBorder;
			for (i = 1; i <= distanceToBorder; i++) {
				if (map[row][col - i] == '#') {
					safeDistance = i - 1;
					break;
				}
			}
			safeDistances[row][col][WEST] = safeDistance;
			break;
		case EAST:
			distanceToBorder = cols - 1 - col;
			safeDistance = distanceToBorder;
			for (i = 1; i <= distanceToBorder; i++) {
				if (map[row][col + i] == '#') {
					safeDistance = i - 1;
					break;
				}
			}
			safeDistances[row][col][EAST] = safeDistance;
			break;
		}
	}
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	for (row = 0; row < rows; row++)
		for (col = 0; col < cols; col++)
			calculateSafeDistance(row, col, rows, cols);

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1000
#define X 0
#define Y 1

struct instruction {
	char dir;
	int len;
};

struct coord {
	int x;
	int y;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[100000];

int invalidInstruction (int * x, int * y, int m, int n, int numInst) {
	char dir; int len;
	int j;

	dir = instructions[numInst].dir;
	len = instructions[numInst].len;

	switch(dir) {
	case 'N':
		for (j = 1; j <= len; j++)
			if (*y - j < 0 || map[*y - j][*x] == '#')
				return 1;
		*y -= len;
		break;
	case 'S':
		for (j = 1; j <= len; j++)
			if (*y + j >= n || map[*y + j][*x] == '#')
				return 1;
		*y += len;
		break;
	case 'W':
		for (j = 1; j <= len; j++)
			if (*x - j < 0 || map[*y][*x - j] == '#')
				return 1;
		*x -= len;
		break;
	case 'E':
		for (j = 1; j <= len; j++)
			if (*x + j >= m || map[*y][*x + j] == '#')
				return 1;
		*x += len;
		break;
	}
	return 0;
}

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;

	x = sights[numSight].x; y = sights[numSight].y;

	for (i = 0; i < numInstrs; i++) {
		if (invalidInstruction (&x, &y, m, n, i))
			return 0;
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.y][oneSight.x] < map[otherSight.y][otherSight.x];
}

int main(int argc, char **argv) {
	int n, m, i, j, k;
	int valid; char dir; int len;
	int numSights = 0;

	scanf("%d %d\n", &n, &m);

	for (i = 0; i < n; i++) {
		fgets (map[i], MAX, stdin);

		for (j = 0; j < m; j++) {
			if (map[i][j] != '#' && map[i][j] != '.') {
				sights[numSights].y = i;
				sights[numSights].x = j;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, m, n, k)) {
			printf("%c", map[sights[i].y][sights[i].x]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


/* Renato Augusto Vieira Nishimori - 5121731 */

#include <stdio.h>
#include <algorithm>
using namespace std;

#define MAX 1024
#define NORTH 0
#define SOUTH 1
#define WEST 2
#define EAST 3

struct instruction {
	char dir;
	int len;
};

struct coord {
	int row;
	int col;
};

char map[MAX][MAX];
coord sights[32];
struct instruction instructions[200000];
short safeDistance[MAX][MAX][4];

int tryInstructions (int numSight, int m, int n, int numInstrs) {
	int i, x, y;
	char dir; int len;

	x = sights[numSight].col; y = sights[numSight].row;

	for (i = 0; i < numInstrs; i++) {
		dir = instructions[i].dir;
		len = instructions[i].len;

		switch(dir) {
		case 'N':
			if (safeDistance[y][x][NORTH] < len)
				return 0;
			y -= len;
			break;
		case 'S':
			if (safeDistance[y][x][SOUTH] < len)
				return 0;
			y += len;
			break;
		case 'W':
			if (safeDistance[y][x][WEST] < len)
				return 0;
			x -= len;
			break;
		case 'E':
			if (safeDistance[y][x][EAST] < len)
				return 0;
			x += len;
			break;
		}
	}
	return 1;
}

bool sightCmp (coord oneSight, coord otherSight) {
	return map[oneSight.row][oneSight.col] < map[otherSight.row][otherSight.col];
}

void calculateSafeDistances (int rows, int cols) {
	int r, c;

	for (r = 1; r < rows; r++)
		for (c = 0; c < cols; c++)
			if (map[r - 1][c] != '#')
				safeDistance[r][c][NORTH] = safeDistance[r - 1][c][NORTH] + 1;

	for (r = rows - 2; r >= 0; r--)
		for (c = 0; c < cols; c++)
			if (map[r + 1][c] != '#')
				safeDistance[r][c][SOUTH] = safeDistance[r + 1][c][SOUTH] + 1;

	for (c = 1; c < cols; c++)
		for (r = 0; r < rows; r++)
			if (map[r][c - 1] != '#')
				safeDistance[r][c][WEST] = safeDistance[r][c - 1][WEST] + 1;

	for (c = cols - 2; c >= 0; c--)
		for (r = 0; r < rows; r++)
			if (map[r][c + 1] != '#')
				safeDistance[r][c][EAST] = safeDistance[r][c + 1][EAST] + 1;
}

int main(int argc, char **argv) {
	int rows, cols, row, col, k;
	int valid; char dir; int len;
	int numSights = 0;
	int i;

	scanf("%d %d\n", &rows, &cols);

	for (row = 0; row < rows; row++) {
		fgets (map[row], MAX, stdin);

		for (col = 0; col < cols; col++) {
			if (map[row][col] != '#' && map[row][col] != '.') {
				sights[numSights].row = row;
				sights[numSights].col = col;
				numSights++;
			}
		}
	}

	sort(sights, sights + numSights, sightCmp);

	scanf("%d\n", &k);
	for (i = 0; i < k; i++) {
		scanf("%c %d\n", &dir, &len);
		instructions[i].dir = dir;
		instructions[i].len = len;
	}

	for (row = 0; row < rows; row++)
		for (col = 0; col < cols; col++)
			safeDistance[row][col][NORTH] = safeDistance[row][col][SOUTH] = safeDistance[row][col][WEST] = safeDistance[row][col][EAST];

	calculateSafeDistances(rows, cols);

	valid = 0;
	for (i = 0; i < numSights; i++) {
		if (tryInstructions(i, cols, rows, k)) {
			printf("%c", map[sights[i].row][sights[i].col]);
			valid = 1;
		}
	}
	if (!valid)
		printf("no solution");
	putchar('\n');

	return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((kart[i][j] >='A')&&(kart[i][j]<='Z')) Q.push(Data(i,j));
     }
  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
     scanf("%c",&napr[i]);
     scanf("%d",&kol[i]);
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((kart[i][j] >='A')&&(kart[i][j]<='Z')) Q.push(Data(i,j));
     }
  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = c;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];
int sum1[1001][1001];
int sum2[1001][1001];
struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
   {
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
  }
  for(int i = 1; i <=n; i++)
    for(int j = 1; j <=m;j++)
      if(kart[i][j] !='#') sum1[i][j] = sum1[i][j-1]+1;
      else sum1[i][j] = 0;
  for(int j = 1; j <=m; j++)
    for(int i = 1; i<=n;i++)
      if(kart[i][j] !='#') sum2[i][j] = sum2[i-1][j]+1;
      else sum2[i][j] = 0;

  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           if(sum1[y][x+x1] - sum1[y][x] != abs(x1)) {OK = false;break;}
         }
         else
         {
           if(sum1[y][x] - sum1[y][x+x1] != abs(x1)) {OK = false;break;}
         }
         if(y1>=0)
         {
           if(sum2[y+y1][x] - sum2[y][x] != abs(y1)) {OK = false;break;}
         }
         else
         {
           if(sum2[y][x] - sum2[y+y1][x] != abs(y1)) {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];
int sum1[1001][1001];
int sum2[1001][1001];
struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
   {
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
  }
  for(int i = 1; i <=n; i++)
    for(int j = 1; j <=m;j++)
      if(kart[i][j] !='#') sum1[i][j] = sum1[i][j-1]+1;
      else sum1[i][j] = sum1[i][j-1];
  for(int j = 1; j <=m; j++)
    for(int i = 1; i<=n;i++)
      if(kart[i][j] !='#') sum2[i][j] = sum2[i-1][j]+1;
      else sum2[i][j] = sum2[i-1][j];

  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           if(sum1[y][x+x1] - sum1[y][x] != abs(x1)) {OK = false;break;}
         }
         else
         {
           if(sum1[y][x] - sum1[y][x+x1] != abs(x1)) {OK = false;break;}
         }
         if(y1>=0)
         {
           if(sum2[y+y1][x] - sum2[y][x] != abs(y1)) {OK = false;break;}
         }
         else
         {
           if(sum2[y][x] - sum2[y+y1][x] != abs(y1)) {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];
int sum1[1001][1001];
int sum2[1001][1001];
struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
   {
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
  }
  for(int i = 1; i <=n; i++)
    for(int j = 1; j <=m;j++)
      if(kart[i][j] !='#') sum1[i][j] = sum1[i][j-1]+1;
      else sum1[i][j] = 0;
  for(int j = 1; j <=m; j++)
    for(int i = 1; i<=n;i++)
      if(kart[i][j] !='#') sum2[i][j] = sum2[i-1][j]+1;
      else sum2[i][j] = 0;

  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           if(sum1[y][x+x1] - sum1[y][x] != abs(x1)) {OK = false;break;}
         }
         else
         {
           if(sum1[y][x] - sum1[y][x+x1] != abs(x1)||(!sum1[y][x+x1])) {OK = false;break;}
         }
         if(y1>=0)
         {
           if(sum2[y+y1][x] - sum2[y][x] != abs(y1)) {OK = false;break;}
         }
         else
         {
           if(sum2[y][x] - sum2[y+y1][x] != abs(y1)||(!sum2[y+y1][x])) {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   char napr[100008];
   int kol[100008];
   char kart[1001][1001];
   int n,m,k,ch;
   char c;
   string str;
   map<char,bool> arr;
   queue<Data> Q;
   scanf("%d%d",&n,&m);
   for(int i  = 1; i <=n; i++)
   {
     scanf("%s",&str);
     for(int j = 1; j <=m; j++)
     {
       kart[i][j] = str[j-1];
       if((kart[i][j] >='A')&&(kart[i][j]<='Z')) Q.push(Data(i,j));
     }
  }
  scanf("%d",&k);
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
     for(int j = 1; j <=m; j++)
     {
       scanf("%c",&kart[i][j]);
       if((kart[i][j] >='A')&&(kart[i][j]<='Z')) Q.push(Data(i,j));
     }
  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
     scanf("%c%d",&napr[i],&kol[i]);
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
   {
     for(int j = 1; j <=m; j++)
     {
       //cin >> c;
       //kart[i][j] = c;
       scanf("%c",&kart[i][j]);
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
     scanf("%c",&c);
  }
  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    //cin >> c >> ch;
    //napr[i] = c;
    //kol[i] = ch;
    scanf("%c%d%c",&napr[i],&kol[i],&c);
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];

struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           for(int j = x; j <= x+x1; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = x+x1; j <= x; j++)
             if( kart[y][j] == '#') {OK = false;break;}
         }
         if(y1>=0)
         {
           for(int j = y; j <= y+y1; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
         else
         {
           for(int j = y+y1; j <= y; j++)
             if( kart[j][x] == '#') {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <cstdio>
#include <list>
#include <set>
#include <deque>
#include <queue>
#include <cstring>

using namespace std;

char kart[1001][1001];
int sum1[1001][1001];
int sum2[1001][1001];
struct Data
{
  int y;int x;
  Data(int a,int b):y(a),x(b){}
};

char napr[100008];
int kol[100008];

int main()
{
   //freopen("input.txt","r",stdin);
   //freopen("output.txt","w",stdout);
   int n,m,k,ch;
   char c;
   map<char,bool> arr;
   queue<Data> Q;
   cin >> n >> m;
   for(int i  = 1; i <=n; i++)
   {
     for(int j = 1; j <=m; j++)
     {
       cin >> c;
       kart[i][j] = c;
       if((c >='A')&&(c<='Z')) Q.push(Data(i,j));
     }
  }
  for(int i = 1; i <=n; i++)
    for(int j = 1; j <=m;j++)
      if(kart[i][j] !='#') sum1[i][j] = sum1[i][j-1]+1;
      else sum1[i][j] = 0;
  for(int j = 1; j <=m; j++)
    for(int i = 1; i<=n;i++)
      if(kart[i][j] !='#') sum2[i][j] = sum2[i-1][j]+1;
      else sum2[i][j] = 0;

  cin >> k;
  for(int i = 0 ; i < k; i++)
  {
    cin >> c >> ch;
    napr[i] = c;
    kol[i] = ch;
  }
  int x1,y1;
  while(!Q.empty())
  {
     Data r = Q.front();
     int x = r.x;
     int y = r.y;
     bool OK = true;
     for(int i = 0; (i < k)&&OK; i++)
     {
       switch(napr[i])
       {
          case 'N':
              x1 = 0;
              y1 = -kol[i];
              break;
          case 'S':
              x1 = 0;
              y1 = kol[i];
              break;
         case 'W':
              x1 = -kol[i];
              y1 = 0;
              break;
          case 'E':
              x1 = kol[i];
              y1 = 0;
              break;
       }
       if((x+x1<1)||(x+x1>m)||(y+y1<1)||(y+y1>n)){ OK = false;break;}
       else
       {
         if(x1>=0)
         {
           if(sum1[y][x+x1] - sum1[y][x] != abs(x1)) {OK = false;break;}
         }
         else
         {
           if(sum1[y][x] - sum1[y][x+x1] != abs(x1)&&sum1[y][x+x1]) {OK = false;break;}
         }
         if(y1>=0)
         {
           if(sum2[y+y1][x] - sum2[y][x] != abs(y1)) {OK = false;break;}
         }
         else
         {
           if(sum2[y][x] - sum2[y+y1][x] != abs(y1)&&sum2[y+y1][x]) {OK = false;break;}
         }
       }
       x = x+x1;y=y+y1;
     }
     if(OK) arr[kart[r.y][r.x]] = 1;
     Q.pop();
  }
  if(arr.size())
  {
  for(char i = 'A'; i <='Z'; i++)
    if(arr[i]) cout << i;
  }
  else cout <<"no solution";
  //system("PAUSE");
}


#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
#include <set>
#include <stack>
#include <string.h>
#define FOR(A, B) for(A = 0; A < B; A++)

using namespace std;

char map[1001][1001];
int d[4][2] = {{-1, 0}, {0, 1}, {0, -1}, {1, 0}};
typedef struct
{
	int d, l;
} ins;
typedef struct
{
	int walls[4];
} waller;
waller w[1001][1001];
ins in[100001];
int dirtoi(char c)
{
	if(c == 'N') return 0;
	if(c == 'E') return 1;
	if(c == 'W') return 2;
	if(c == 'S') return 3;
}

int main()
{
	int i,j,k,l=0,n,m;
	pair<int, int> pos[27];
	scanf("%d %d\n", &n, &m);
	FOR(i, n) {
		FOR(j, m) {
			scanf("%c", &map[i][j]);
			if(map[i][j] >= 'A' && map[i][j] <= 'Z') pos[l++] = make_pair(i,j);
			w[i][j].walls[0] = w[i][j].walls[1] = w[i][j].walls[2] = w[i][j].walls[3] = -1;
		}
		scanf("\n");
	}
	FOR(i, n) FOR(j, m) {
		if(map[i][j] == '#') {
			if(i-1 > 0) w[i-1][j].walls[3] = 1;
			if(j-1 > 0) w[i][j-1].walls[1] = 1;
			if(i+1 < n) w[i+1][j].walls[0] = 1;
			if(j+1 < m) w[i][j+1].walls[2] = 1;
		}
	}
	FOR(i, n) {
		FOR(j, m) {
			if(map[i][j] != '#') {
				if(i-1 > 0 && w[i-1][j].walls[0] != -1) {
					w[i][j].walls[0] = w[i-1][j].walls[0]+1;
				}
				if(j-1 > 0 && w[i][j-1].walls[2] != -1) {
					w[i][j].walls[2] = w[i][j-1].walls[2]+1;
				}
			}
		}
	}
	for(i = n-1; i >=0; i--) {
		for(j = m-1; j>=0; j--) {
			if(map[i][j] != '#') {
	//			if(i+1 < n) w[i+1][j].walls[0] = 1;
	//			if(j+1 < m) w[i][j+1].walls[2] = 1;
				if(i+1 < n && w[i+1][j].walls[3] != -1) {
					w[i][j].walls[3] = w[i+1][j].walls[3]+1;
				}
				if(j+1 < m && w[i][j+1].walls[1] != -1) {
					w[i][j].walls[1] = w[i][j+1].walls[1]+1;
				}
			}
		}
	}
//	FOR(i, n) {
//		FOR(j, m) printf("%d ", w[i][j].walls[3]);
//		printf("\n");
//	}
	scanf("%d\n", &k);
	FOR(i, k) {
		char dir[5];
		scanf("%s %d\n", dir, &in[i].l);
		in[i].d = dirtoi(dir[0]);
	}
	vector<char> ans;
	FOR(i, l) {
		int y = pos[i].first, x = pos[i].second;
		bool okk = true;
		FOR(j, k) {
			int q;
			bool ok = true;
/*			FOR(q, in[j].l) {
				y += d[in[j].d][0];
				x += d[in[j].d][1];
				if(y < 0 || x < 0 || y>= n || x >= m || map[y][x] == '#') {ok =false; break;}
			}*/
			int dx = d[in[j].d][1]*in[j].l;
			int dy = d[in[j].d][0]*in[j].l;
//			printf("%c %d %d %d\n", map[pos[i].first][pos[i].second], y, x, w[y][x].walls[in[j].d]);
			if(w[y][x].walls[in[j].d]-1 < max(abs(dx),abs(dy))) {
				okk = false;
				break;
			}
			y += dy;
			x += dx;
//			if(!ok) { okk = false; break;}
		}
		if(okk) ans.push_back(map[pos[i].first][pos[i].second]);
	}
	sort(ans.begin(), ans.end());
	FOR(i, ans.size()) printf("%c", ans[i]);
	if(ans.size() == 0) printf("no solution");
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define LL long long
#define mod 1000000007

char mp[1000][1001];
int len[100000];
char dir[100000];
string ans;

void check(int sx, int sy, int n, int m, int k)
{
//    cout<<mp[sx][sy]<<' ';
    int x = sx,y = sy;
    int mx,my,l;
    for(int i=0;i<k;i++)
    {
        if(dir[i]=='N') mx=-1,my=0;
        if(dir[i]=='S') mx=1,my=0;
        if(dir[i]=='W') mx=0,my=-1;
        if(dir[i]=='E') mx=0,my=1;

        l = len[i];
        while(l)
        {
            x+=mx;
            y+=my;
            l--;
            if(x<0 || y<0 || x>=n || y>=m || mp[x][y]=='#')
                return;
        }
    }
    ans+=mp[sx][sy];
}

int main()
{
    int n,m,i,j,k;

    cin>>n>>m;
    for(i=0;i<n;i++)
        cin>>mp[i];

    cin>>k;
    for(i=0;i<k;i++)
        cin>>dir[i]>>len[i];

    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
            if(isalpha(mp[i][j]))
                check(i,j,n,m,k);

    if(ans.empty())
        cout<<"no solution";
    else
    {
        sort(ans.begin(),ans.end());
        cout<<ans;
    }
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

int n, q, l, r;
string s, t;

int x[10], cp, dp;

int main() {
	cin >> n >> q;
	cin >> s;

	while (q--) {
		cin >> l >> r;

		t = s;

		cp = l - 1;
		dp = 1;
		memset(x, 0, sizeof x);
		while (cp >= l - 1 && cp < r) {
			if (s[cp] >= '0' && s[cp] <= '9') {
				x[s[cp] - '0']++;
				s[cp] = (char)(s[cp] - 1);

				if (s[cp] < '0') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				else
					cp += dp;

				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
			else if (s[cp] == '<' || s[cp] == '>') {
				if (s[cp] == '<')
					dp = -1;
				else if (s[cp] == '>')
					dp = 1;

				if (s[cp] == '>' && cp+1 <= s.length() - 1 && s[cp+1] == '<') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				if (s[cp] == '<' && cp-1 >= 0 && s[cp-1] == '>') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}

				cp += dp;
				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
		}

		for (int i = 0; i < 10; i++) {
			if (i != 0)
				cout << ' ';
			cout << x[i];
		}
		cout << endl;

		s = t;
	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

int n, q, l, r;
string s, t;

int x[10], cp, dp;

int main() {
	cin >> n >> q;
	cin >> s;

	while (q--) {
		cin >> l >> r;
		l--;
		t = s;

		cp = l;
		dp = 1;
		memset(x, 0, sizeof x);
		while (cp >= l && cp < r) {
			//cout << s << endl;
			if (cp < 0 || cp >= r || cp >= s.length())
				break;

			if (s[cp] >= '0' && s[cp] <= '9') {
				x[s[cp] - '0']++;
				s[cp] = (char)(s[cp] - 1);
				cp += dp;

				if (cp < 0 || cp >= r || cp >= s.length())
					break;

				if (s[cp - dp] < '0') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp - dp)
							t2 += s[i];
					s = t2;
					cp -= dp;
				}

				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
			else if (s[cp] == '<' || s[cp] == '>') {
				if (s[cp] == '<')
					dp = -1;
				else if (s[cp] == '>')
					dp = 1;

				if (s[cp] == '>' && cp+1 <= s.length() - 1 && s[cp+1] == '<') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				if (s[cp] == '<' && cp-1 >= 0 && s[cp-1] == '>') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}

				cp += dp;
				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
		}

		for (int i = 0; i < 10; i++) {
			if (i != 0)
				cout << ' ';
			cout << x[i];
		}
		cout << endl;

		s = t;
	}

	return 0;
}


#include <iostream>
#include <string>
using namespace std;

int main() {
	string s;
	int Len, Qry;
	cin >> Len >> Qry >> s;
	while (Qry --) {
		int pL, pR;
		cin >> pL >> pR;
		string t;
		t = s.substr(pL - 1, pR - pL + 1);
		int cp = 0, dp = 1;
		int Count[10] = {0};
		while(cp >= 0 && cp < t.length())
		{
			if(t[cp] >= '0' && t[cp] <= '9')
			{
				Count[t[cp] - '0'] ++ ;
				if(t[cp] == '0')
				{
					t.erase(cp, 1);
					if(!dp)
					 -- cp;
				}else
				{
					t[cp] --;
					cp += dp ? 1 : -1;
				}
			}else
			{
				if(t[cp] == '>')
				{
					dp = 1;
					++ cp;
					if(cp < t.length() && (t[cp] == '>' || t[cp] == '<'))
						t.erase(-- cp, 1);
				}else
				{
					dp = 0;
					-- cp;
					if(cp >= 0 && (t[cp ] == '>' || t[cp] == '<'))
						t.erase(cp + 1, 1);
				}
			}
		}
		for(int i(0); i < 10; ++ i)
			cout << Count[i] << " ";
		cout << endl;
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

int n, q, l, r;
string s, t;

int x[10], cp, dp, cp2;

int main() {
	cin >> n >> q;
	cin >> s;

	while (q--) {
		cin >> l >> r;
		l--;
		t = s;

		cp = 0;
		dp = 1;
		memset(x, 0, sizeof x);

		s = s.substr(l, r - l);
		//cout << s << endl;
		while (cp >= 0 && cp < s.length()) {
			if (s[cp] >= '0' && s[cp] <= '9') {
				x[s[cp] - '0']++;
				cp += dp;
				s[cp-dp] = (char)(s[cp-dp] - 1);

				if (cp < 0 || cp >= r || cp >= s.length())
					break;
				if (s[cp-dp] < '0') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp-dp)
							t2 += s[i];
					s = t2;
					cp -= dp;
				}
			}
			else if (s[cp] == '<' || s[cp] == '>') {
				if (s[cp] == '<')
					dp = -1;
				else if (s[cp] == '>')
					dp = 1;

				if (s[cp] == '>' && cp+1 <= s.length() - 1 && s[cp+1] == '<') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				if (s[cp] == '<' && cp-1 >= 0 && s[cp-1] == '>') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}

				cp += dp;
				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
		}

		for (int i = 0; i < 10; i++) {
			if (i != 0)
				cout << ' ';
			cout << x[i];
		}
		cout << endl;

		s = t;
	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

int n, q, l, r;
string s, t;

int x[10], cp, dp;

int main() {
	cin >> n >> q;
	cin >> s;

	while (q--) {
		cin >> l >> r;

		t = s;

		cp = l - 1;
		dp = 1;
		memset(x, 0, sizeof x);
		while (cp >= l - 1 && cp < r) {
			if (s[cp] >= '0' && s[cp] <= '9') {
				x[s[cp] - '0']++;
				s[cp] = (char)(s[cp] - 1);

				if (s[cp] < '0') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				else
					cp += dp;
			}
			else if (s[cp] == '<' || s[cp] == '>') {
				if (s[cp] == '<')
					dp = -1;
				else if (s[cp] == '>')
					dp = 1;

				if (s[cp] == '>' && cp+1 <= s.length() - 1 && s[cp+1] == '<') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				if (s[cp] == '<' && cp-1 >= 0 && s[cp-1] == '>') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}

				cp += dp;
				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
		}

		for (int i = 0; i < 10; i++) {
			if (i != 0)
				cout << ' ';
			cout << x[i];
		}
		cout << endl;

		s = t;
	}

	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;

int n, q, l, r;
string s, t;

int x[10], cp, dp;

int main() {
	cin >> n >> q;
	cin >> s;

	while (q--) {
		cin >> l >> r;
		l--;
		t = s;

		cp = l;
		dp = 1;
		memset(x, 0, sizeof x);
		while (cp >= l && cp < r) {
			cout << s << endl;
			if (cp < 0 || cp >= r || cp >= s.length())
				break;

			if (s[cp] >= '0' && s[cp] <= '9') {
				x[s[cp] - '0']++;
				s[cp] = (char)(s[cp] - 1);
				cp += dp;

				if (cp < 0 || cp >= r || cp >= s.length())
					break;

				if (s[cp - dp] < '0') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp - dp)
							t2 += s[i];
					s = t2;
					cp -= dp;
				}

				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
			else if (s[cp] == '<' || s[cp] == '>') {
				if (s[cp] == '<')
					dp = -1;
				else if (s[cp] == '>')
					dp = 1;

				if (s[cp] == '>' && cp+1 <= s.length() - 1 && s[cp+1] == '<') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}
				if (s[cp] == '<' && cp-1 >= 0 && s[cp-1] == '>') {
					string t2 = "";
					for (int i = 0; i < s.length(); i++)
						if (i != cp)
							t2 += s[i];
					s = t2;
				}

				cp += dp;
				if (cp < 0 || cp >= r || cp >= s.length())
					break;
			}
		}

		for (int i = 0; i < 10; i++) {
			if (i != 0)
				cout << ' ';
			cout << x[i];
		}
		cout << endl;

		s = t;
	}

	return 0;
}


#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;
stack<int> pro;
int ans[10];

int main()
{
    string d;
    int n,m;
    cin>>n>>m;
    cin>>d;
    for (int i=0;i<m;i++){
        int l,r,q=0,p,max,t;
        cin>>l>>r;
        clr(ans,0);
        for (int j=l-1;j<r;j++){
            if (d[j]=='>'&&(pro.empty()||pro.top()!='>')){
                pro.push('>');
                q++;
                //cout<<">"<<j;
            }
            if (d[j]>='0'&&d[j]<='9'){
                pro.push(d[j]-'0');
                //cout<<"!"<<d[j]-'0';
            }
            if (d[j]=='<'){
                if (!pro.empty()&&pro.top()=='>'){
                    pro.pop();
                    q--;
                }
                int max,t=1;
                while (q){
                    //cout<<"<"<<q<<":";
                    max=0;
                    while ((p=pro.top())!='>'){
                        //cout<<p<<",";
                        pro.pop();
                        if (p>max)
                            max=p;
                        for (int k=0;k<=p;k++)
                            ans[k]++;
                    }
                    if (max%2){
                        pro.pop();
                        q--;
                    }else{
                        t=0;
                        break;
                    }
                };
                if (t){
                    q=-1;
                    break;
                }
            }
        }
        if (q!=-1)
            q=0;
        while (!pro.empty()){
            p=pro.top();
            pro.pop();
            if (p=='<'||p=='>')
                continue;
            //cout<<"$"<<p;
            for (int k=p;k>=p+q&&k>=0;k--)
                ans[k]++;
        }
        for (int j=0;j<10;j++)
            cout<<ans[j]<<" ";
        cout<<endl;
    }
}


#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;
stack<int> pro;
int ans[10];

int main()
{
    string d;
    int n,m;
    cin>>n>>m;
    cin>>d;
    for (int i=0;i<m;i++){
        int l,r,q=0,p,max;
        cin>>l>>r;
        clr(ans,0);
        for (int j=l-1;j<r;j++){
            if (d[j]=='>'&&(pro.empty()||pro.top()!='>')){
                pro.push('>');
                q++;
                //cout<<">"<<j;
            }
            if (d[j]>='0'&&d[j]<='9'){
                pro.push(d[j]-'0');
                //cout<<"!"<<d[j]-'0';
            }
            if (d[j]=='<'){
                int max;
                while (q){
                    //cout<<"<"<<q<<":";
                    max=0;
                    while ((p=pro.top())!='>'){
                        //cout<<p<<",";
                        pro.pop();
                        if (p>max)
                            max=p;
                        for (int k=0;k<=p;k++)
                            ans[k]++;
                    }
                    if (max%2){
                        pro.pop();
                        q--;
                    }else
                        break;
                };
                if (!q&&max%2){
                    q=-1;
                    break;
                }
            }
        }
        if (q!=-1)
            q=0;
        while (!pro.empty()){
            p=pro.top();
            pro.pop();
            if (p=='<'||p=='>')
                continue;
            for (int k=p+q;k<=p;k++)
                ans[k]++;
        }
        for (int j=0;j<10;j++)
            cout<<ans[j]<<" ";
        cout<<endl;
    }
}


#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;
stack<int> pro;
int ans[10];

int main()
{
    string d;
    int n,m;
    cin>>n>>m;
    cin>>d;
    for (int i=0;i<m;i++){
        int l,r,q=0,p,max;
        cin>>l>>r;
        clr(ans,0);
        for (int j=l-1;j<r;j++){
            if (d[j]=='>'&&(pro.empty()||pro.top()!='>')){
                pro.push('>');
                q++;
                //cout<<">"<<j;
            }
            if (d[j]>='0'&&d[j]<='9'){
                pro.push(d[j]-'0');
                //cout<<"!"<<d[j]-'0';
            }
            if (d[j]=='<'){
                int max;
                while (q){
                    //cout<<"<"<<q<<":";
                    max=0;
                    while ((p=pro.top())!='>'){
                        //cout<<p<<",";
                        pro.pop();
                        if (p>max)
                            max=p;
                        for (int k=0;k<=p;k++)
                            ans[k]++;
                    }
                    if (max%2){
                        pro.pop();
                        q--;
                    }else
                        break;
                };
                if (!q&&!(max%2)){
                    q=-1;
                    break;
                }
            }
        }
        if (q!=-1)
            q=0;
        while (!pro.empty()){
            p=pro.top();
            pro.pop();
            if (p=='<'||p=='>')
                continue;
            //cout<<"$"<<p;
            for (int k=p;k>=p+q&&k>=0;k--)
                ans[k]++;
        }
        for (int j=0;j<10;j++)
            cout<<ans[j]<<" ";
        cout<<endl;
    }
}


#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;
stack<int> pro;
int ans[10];

int main()
{
    string d;
    int n,m;
    cin>>n>>m;
    cin>>d;
    for (int i=0;i<m;i++){
        int l,r,q=0,p,max,t;
        cin>>l>>r;
        clr(ans,0);
        for (int j=l-1;j<r;j++){
            if (d[j]=='>'&&(pro.empty()||pro.top()!='>')){
                pro.push('>');
                q++;
                //cout<<">"<<j;
            }
            if (d[j]>='0'&&d[j]<='9'){
                pro.push(d[j]-'0');
                //cout<<"!"<<d[j]-'0';
            }
            if (d[j]=='<'){
                int max,t=1;
                while (q){
                    //cout<<"<"<<q<<":";
                    max=0;
                    while ((p=pro.top())!='>'){
                        //cout<<p<<",";
                        pro.pop();
                        if (p>max)
                            max=p;
                        for (int k=0;k<=p;k++)
                            ans[k]++;
                    }
                    if (max%2){
                        pro.pop();
                        q--;
                    }else{
                        t=0;
                        break;
                    }
                };
                if (t){
                    q=-1;
                    break;
                }
            }
        }
        if (q!=-1)
            q=0;
        while (!pro.empty()){
            p=pro.top();
            pro.pop();
            if (p=='<'||p=='>')
                continue;
            //cout<<"$"<<p;
            for (int k=p;k>=p+q&&k>=0;k--)
                ans[k]++;
        }
        for (int j=0;j<10;j++)
            cout<<ans[j]<<" ";
        cout<<endl;
    }
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
    char s[110],t[110];
    int cp,dp,l,r,n,q,m,count[10];
    scanf("%d%d",&n,&q);
    scanf("%s",s);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        strncpy(t,s+l-1,r);
        m=r-l+1;
        memset(count,0,sizeof(count));
        cp=0;dp=1;
        while(cp>=0&&cp<m)
        {
            if('1'<=t[cp]&&t[cp]<='9')
            {
                ++count[t[cp]-'0'];
                t[cp]=t[cp]-1;
                cp+=dp;
            }
            else if(t[cp]=='0')
            {
                ++count[0];
                for(int i=cp+1;i<m;i++) t[i-1]=t[i];
                --m;
                cp+=dp;
            }
            else if(t[cp]=='<')
            {
                dp=-1;
                cp+=dp;
                if(!(cp>=0))    break;
                if(t[cp]=='<'||t[cp]=='>')
                {
                    for(int i=cp;i<m;i++)   t[i-1]=t[i];
                    --m;
                }
            }
            else if(t[cp]=='>')
            {
                dp=1;
                cp+=dp;
                if(!(cp<m))    break;
                if(t[cp]=='<'||t[cp]=='>')
                {
                    for(int i=cp;i<m;i++)   t[i-1]=t[i];
                    --m;
                }
            }
        }
        for(int i=0;i<10;i++)   printf("%d ",count[i]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
    char s[110],t[110];
    int cp,dp,l,r,n,q,m,count[10];
    scanf("%d%d",&n,&q);
    scanf("%s",s);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        strncpy(t,s+l-1,r);
        m=r-l+1;
        memset(count,0,sizeof(count));
        cp=0;dp=1;
        while(cp>=0&&cp<m)
        {
            if('1'<=t[cp]&&t[cp]<='9')
            {
                ++count[t[cp]-'0'];
                t[cp]=t[cp]-1;
            }
            else if(t[cp]=='0')
            {
                ++count[0];
                for(int i=cp;i<m-1;i++) t[i]=t[i+1];
                --m;
            }
            else if(t[cp]=='<')
            {
                dp=-1;
                if(cp-1<0)  break;
                if(t[cp-1]=='<'||t[cp-1]=='>')
                {
                    for(int i=cp;i<m-1;i++)   t[i]=t[i+1];
                    --m;
                }
            }
            else if(t[cp]=='>')
            {
                dp=1;
                if(cp+1>=m)    break;
                if(t[cp+1]=='<'||t[cp+1]=='>')
                {
                    for(int i=cp;i<m-1;i++)   t[i]=t[i+1];
                    --m;
                }
            }
            cp+=dp;
        }
        for(int i=0;i<10;i++)   printf("%d ",count[i]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
    char s[110],t[110];
    int cp,dp,l,r,n,q,m,count[10];
    scanf("%d%d",&n,&q);
    scanf("%s",s);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        strncpy(t,s+l-1,r);
        m=r-l+1;
        memset(count,0,sizeof(count));
        cp=0;dp=1;
        while(cp>=0&&cp<m)
        {
            if('1'<=t[cp]&&t[cp]<='9')
            {
                ++count[t[cp]-'0'];
                t[cp]=t[cp]-1;
                cp+=dp;
            }
            else if(t[cp]=='0')
            {
                ++count[0];
                for(int i=cp+1;i<m;i++) t[i-1]=t[i];
                --m;
                cp+=dp;
            }
            else if(t[cp]=='<')
            {
                dp=-1;
                cp+=dp;
                if(!(cp>=0))    break;
                if(t[cp]=='<'||t[cp]=='>')
                {
                    for(int i=cp+1;i<m-1;i++)   t[i]=t[i+1];
                    --m;
                }
            }
            else if(t[cp]=='>')
            {
                dp=1;
                cp+=dp;
                if(!(cp<m))    break;
                if(t[cp]=='<'||t[cp]=='>')
                {
                    for(int i=cp;i<m;i++)   t[i-1]=t[i];
                    --m;
                }
            }
        }
        for(int i=0;i<10;i++)   printf("%d ",count[i]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
    char s[110],t[110];
    int cp,dp,l,r,n,q,m,count[10];
    scanf("%d%d",&n,&q);
    scanf("%s",s);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        strncpy(t,s+l-1,r);
        m=r-l+1;
        memset(count,0,sizeof(count));
        cp=0;dp=1;
        while(cp>=0&&cp<m)
        {
            if('1'<=t[cp]&&t[cp]<='9')
            {
                ++count[t[cp]-'0'];
                t[cp]=t[cp]-1;
            }
            else if(t[cp]=='0')
            {
                ++count[0];
                for(int i=cp+1;i<m;i++) t[i-1]=t[i];
                --m;
            }
            else if(t[cp]=='<'||t[cp]=='>')
            {
                if(dp==1)
                {
                    if(cp-dp<0)  continue;
                    for(int i=cp;i<m;i++)   t[i-1]=t[i];
                    --m;
                }else
                {
                    for(int i=cp+1;i<m-1;i++)   t[i]=t[i+1];
                    --m;
                }
                if(t[cp]=='<')  dp=-1;
                else    dp=1;
            }
            cp+=dp;
        }
        for(int i=0;i<10;i++)   printf("%d ",count[i]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
    char s[110],t[110];
    int cp,dp,l,r,n,q,m,count[10];
    scanf("%d%d",&n,&q);
    scanf("%s",s);
    while(q--)
    {
        scanf("%d%d",&l,&r);
        strncpy(t,s+l-1,r);
        r=r-l+1;
        l=0;
        memset(count,0,sizeof(count));
        cp=0;dp=1;
        while(cp>=l&&cp<r)
        {
            if('1'<=t[cp]&&t[cp]<='9')
            {
                ++count[t[cp]-'0'];
                t[cp]=t[cp]-1;
            }
            else if(t[cp]=='0')
            {
                ++count[0];
                if(dp==1)
                {
                    for(int i=cp;i>l;i--) t[i]=t[i-1];
                    ++l;
                }else
                {
                    for(int i=cp;i<r-1;i++) t[i]=t[i+1];
                    --r;
                }
            }
            else if(t[cp]=='<')
            {
                dp=-1;
                if(cp-1<l)  break;
                if(t[cp-1]=='<'||t[cp-1]=='>')
                {
                    for(int i=cp;i<r-1;i++)   t[i]=t[i+1];
                    --r;
                }
            }
            else if(t[cp]=='>')
            {
                dp=1;
                if(cp+1>=r)    break;
                if(t[cp+1]=='<'||t[cp+1]=='>')
                {
                    for(int i=cp;i>l;i--)   t[i]=t[i-1];
                    ++l;
                }
            }
            cp+=dp;
        }
        for(int i=0;i<10;i++)   printf("%d ",count[i]);
        printf("\n");
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int m;
void solve()
{
    /* printf("%d ",m);
       F(i,1,m)
       printf("%c",t[i]);
       */
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
        if(l<1||l>m)
            break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
                num[t[l]-'0']++;
                if(t[l]>'0'&&t[l]<='9'){
                    t[l]=t[l]-1;
        }
                else
                    t[l]='a';
                if(r==1)
                    l++;
                if(r==-1)
                    l--;
            }
        }
    //F(i,1,m)
    //    printf("%c ",t[i]);
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char str[N],ss[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(str);
        scanf("%s",str+1);
    strcpy(ss,str);
        while(q--)
        {
        strcpy(str,ss);
           /*printf("%d ",n);
            F(i,1,n)
              printf("%c",str[i]);printf("\n");
           // cin>>xx;
        */
            int l,r;
            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l,r)
                t[++m]=str[i];
           solve();
        }
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int m;
void solve()
{
       /*  printf("%d ",m);
       F(i,1,m)
       printf("%c",t[i]);
       int xx;cin>>xx; */
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
        if(l<1||l>m)
            break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
                num[t[l]-'0']++;
                if(t[l]>'0'&&t[l]<='9'){
                    t[l]=t[l]-1;
        }
                else
                    t[l]='a';
                if(r==1)
                    l++;
                if(r==-1)
                    l--;
            }
        }
    //printf("%s ",str+1);
    //F(i,1,m)
    //    printf("%c ",t[i]);
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char str[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(str);
        scanf("%s",str+1);
        while(q--)
        {
           //cout<<"***";
          // printf("%d ",n);
           //int xx;cin>>xx;
           // F(i,1,n)
           //    printf("%c",str[i]);printf("\n");
           // cin>>xx;
            int l,r;
            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l,r)
                t[++m]=str[i];
            solve();
            //printf("***");
            //printf("%s ",str+1);
            //cin>>xx;
        }
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 110
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int m;
void solve()
{
       /*  printf("%d ",m);
       F(i,1,m)
       printf("%c",t[i]);
       int xx;cin>>xx; */
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
        if(l<1||l>m)
            break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
                num[t[l]-'0']++;
                if(t[l]>'0'&&t[l]<='9'){
                    t[l]=t[l]-1;
        }
                else
                    t[l]='a';
                if(r==1)
                    l++;
                if(r==-1)
                    l--;
            }
        }
    //printf("%s ",str+1);
    //F(i,1,m)
    //    printf("%c ",t[i]);
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char str[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(str);
        scanf("%s",str+1);
        while(q--)
        {
           //cout<<"***";
          // printf("%d ",n);
           //int xx;cin>>xx;
           // F(i,1,n)
           //    printf("%c",str[i]);printf("\n");
           // cin>>xx;
            int l,r;
            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l,r)
                t[++m]=str[i];
            solve();
            //printf("***");
            //printf("%s ",str+1);
            //cin>>xx;
        }
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int m;
void solve()
{
     printf("%d ",m);
       F(i,1,m)
       printf("%c",t[i]);
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
        if(l<1||l>m)
            break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
                num[t[l]-'0']++;
                if(t[l]>'0'&&t[l]<='9'){
                    t[l]=t[l]-1;
        }
                else
                    t[l]='a';
                if(r==1)
                    l++;
                if(r==-1)
                    l--;
            }
        }
    //F(i,1,m)
    //    printf("%c ",t[i]);
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char str[N],ss[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(str);
        scanf("%s",str+1);
    strcpy(ss,str);
        while(q--)
        {
        strcpy(str,ss);
           printf("%d ",n);
            F(i,1,n)
              printf("%c",str[i]);printf("\n");
           // cin>>xx;
            int l,r;
            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l,r)
                t[++m]=str[i];
           solve();
        }
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int l,r;
int m;
void solve()
{
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
                if(l<1||l>m)
                    break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
            num[t[l]-'0']++;
            if(t[l]>'0'&&t[l]<='9'){
                t[l]=t[l]-1;
            }
            else
                t[l]='a';
            if(r==1)
                l++;
            if(r==-1)
                l--;
        }
    }
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char ss[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(ss);
        scanf("%s",ss+1);
        while(q--)
        {

            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l,r)
                t[++m]=ss[i];
            solve();
        }
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
#define N 1100
#define clr(a) memset(a,0,sizeof(a))
#define F(i,a,n) for(int i=a;i<=n;i++)
char t[N];
int l,r;
int m;
void solve()
{
    int l=1,r=1;
    int num[15];
    clr(num);
    while(1)
    {
        if(l<1||l>m)
            break;
        if(t[l]=='<'||t[l]=='>')
        {
            int ll=l;
            if(t[l]=='<')
                r=-1;
            else
                r=1;
            if(r==1)
                l++;
            else
                l--;
            if(l<1||l>m)
                break;
            if(t[l]=='>'||t[l]=='<')
            {
                t[ll]='a';
            }
            else if(t[l]=='a')
            {
                while(1)
                {
                    if(r==1)
                        l++;
                    else
                        l--;
                    if(l<1||l>m)
                        break;
                    if(t[l]!='a')
                        break;
                }
                if(l<1||l>m)
                    break;
                if(t[l]=='>'||t[l]=='<')
                {
                    t[ll]='a';
                }
            }
        }
        else{
            num[t[l]-'0']++;
            if(t[l]>'0'&&t[l]<='9'){
                t[l]=t[l]-1;
            }
            else
                t[l]='a';
            if(r==1)
                l++;
            if(r==-1)
                l--;
        }
    }
    F(i,0,9)
        printf("%d ",num[i]);
    printf("\n");
    return ;
}
int main()
{
    int n,q;
    char ss[N];
    while(~scanf("%d%d",&n,&q))
    {
        clr(ss);
        scanf("%s",ss);
        while(q--)
        {

            scanf("%d %d",&l,&r);
            clr(t);
            m=0;
            F(i,l-1,r-1)
                t[++m]=ss[i];
            solve();
        }
    }
    return 0;
}