#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 15
#define NUM 24

struct LOC{
	int row,col;
};

struct Info{
	void set(int arg_row,int arg_col,int arg_state){
		row = arg_row;
		col = arg_col;
		state = arg_state;
	}
	int row,col,state;
};

struct Edge{
	Edge(Info arg_from,Info arg_to){

		from.set(arg_from.row,arg_from.col,arg_from.state);
		to.set(arg_to.row,arg_to.col,arg_to.state);
	}
	Info from,to;
};

//0:上 1:北 2:東 3:西 4:南 5:裏側

class Dice{
public:

	void roll(char dst){
		for(int i = 0; i < 6; i++) work[i] = number[i];
		switch(dst){
		case 'E':
			setNumber(work[3],work[1],work[0],work[5],work[4],work[2]);
			break;
		case 'S':
			setNumber(work[1],work[5],work[2],work[3],work[0],work[4]);
			break;
		case 'N':
			setNumber(work[4],work[0],work[2],work[3],work[5],work[1]);
			break;
		case 'W':
			setNumber(work[2],work[1],work[5],work[0],work[4],work[3]);
			break;
		}
	};

	int getTop(){
		return number[0];
	}

	void setNumber(int n0,int n1,int n2,int n3,int n4,int n5){
		number[0] = n0;
		number[1] = n1;
		number[2] = n2;
		number[3] = n3;
		number[4] = n4;
		number[5] = n5;
	}

	void init(){
		setNumber(0,1,4,2,3,5); ////0:上 1:北 2:東 3:西 4:南 5:裏側
	}

	void copy(Dice arg){

		for(int i = 0; i < 6; i++){
			number[i] = arg.number[i];
		}
	}

	int number[6],work[6];
};

int H,W;
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
char base_map[SIZE][SIZE];
char order[NUM+1] = "NNNNWNNNWNNNENNNENNNWNNN";
string dp[SIZE][SIZE][25];
LOC start,goal;
string words[6];
vector<Dice> DICE;
vector<Edge> edge;


bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

int get_state(Dice dice){

	bool FLG;

	for(int i = 0; i < NUM; i++){
		FLG = true;
		for(int k = 0; k < 6; k++){
			if(dice.number[k] != DICE[i].number[k]){
				FLG = false;
				break;
			}
		}
		if(FLG)return i;
	}

	return -1; //must not reach here
}


int main(){

	scanf("%d %d",&H,&W);

	for(int row = 0; row < H; row++){

		scanf("%s",base_map[row]);
	}

	getchar();

	for(int i = 0; i < 6; i++){

		getline(cin, words[i]);
	}

	scanf("%d %d",&start.row,&start.col);
	start.row--;
	start.col--;

	scanf("%d %d",&goal.row,&goal.col);
	goal.row--;
	goal.col--;

	Dice dice;
	dice.init();

	Dice start_dice;
	start_dice.copy(dice);

	//すべての状態を作る
	for(int state = 0; state < NUM; state++){
		dice.roll(order[state]);
		DICE.push_back(dice);
	}

	int start_state = get_state(start_dice);

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == '.')continue;
			for(int state = 0; state < 24; state++){
				Info from;
				from.set(row,col,state);

				for(int i = 0; i < 4; i++){

					int next_row = row+diff_row[i];
					int next_col = col+diff_col[i];
					if(!rangeCheck(next_row,next_col))continue;

					Info to;
					Dice tmp;
					tmp.copy(DICE[state]);

					switch(i){
					case 0: //上へ
						if(base_map[row][col] == '+' || base_map[row][col] == '|' || base_map[row][col] == '^'){
							tmp.roll('N');
							to.set(next_row,next_col,get_state(tmp));
							edge.push_back(Edge(from,to));
						}
						break;
					case 1: //左のセルへ
						if(base_map[row][col] == '+' || base_map[row][col] == '-' || base_map[row][col] == '<'){
							tmp.roll('W');
							to.set(next_row,next_col,get_state(tmp));
							edge.push_back(Edge(from,to));
						}
						break;
					case 2: //右のセルへ
						if(base_map[row][col] == '+' || base_map[row][col] == '-' || base_map[row][col] == '>'){
							tmp.roll('E');
							to.set(next_row,next_col,get_state(tmp));
							edge.push_back(Edge(from,to));
						}
						break;
					case 3: //手前のセルへ
						if(base_map[row][col] == '+' || base_map[row][col] == '|' || base_map[row][col] == 'v'){
							tmp.roll('S');
							to.set(next_row,next_col,get_state(tmp));
							edge.push_back(Edge(from,to));
						}
						break;
					}
				}
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			for(int state = 0; state < NUM; state++){
				dp[row][col][state] = "no";
			}
		}
	}

	for(int state = 0; state < NUM; state++){

		dp[goal.row][goal.col][state] = words[DICE[state].getTop()];
	}

	int LIMIT = H*W*20; //適当なしきい値
	//ベルマンフォード
	bool updated;
	int count = 0;

	while(count < LIMIT+1){
		updated = false;

		Info from,to;

		for(int i = 0; i < edge.size(); i++){

			from = edge[i].from;
			to = edge[i].to;

			//★★逆向きに計算するので注意★
			if(dp[to.row][to.col][to.state] == "no")continue;

			string next_str = words[DICE[from.state].getTop()] + dp[to.row][to.col][to.state]; //★★ゴール方向から逆に動く

			if(dp[from.row][from.col][from.state] == "no" || dp[from.row][from.col][from.state] > next_str){

				dp[from.row][from.col][from.state] = next_str;
				updated = true;
				if(count > H*W*10 && from.row == start.row && from.col == start.col && from.state == start_state){ //適当に打ち切り
					printf("infinite\n");
					return 0;
				}
			}
		}
		if(!updated)break;
		count++;
	}

	printf("%s\n",dp[start.row][start.col][start_state].c_str());

	return 0;
}

