#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

unsigned long xor128(){
    static unsigned long x=123456789,y=362436069,z=521288629,w=88675123;
    unsigned long t;
    t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) );
}

class Dice
{
public:
    vector<int> pip; // 東南西北上下の目
    Dice(){
        pip.assign(6, -1);
    }
    void roll(int d){ // 東南西北右左に回転
        int dir[][4] = {{4,2,5,0},{4,3,5,1},{4,0,5,2},{4,1,5,3},{0,3,2,1},{0,1,2,3}};
        int tmp = pip[dir[d][0]];
        for(int i=0; i<3; ++i)
            pip[dir[d][i]] = pip[dir[d][i+1]];
        pip[dir[d][3]] = tmp;
    }
    bool operator==(const Dice& d) const{
        return pip == d.pip;
    }
};

class Data
{
public:
    int y, x;
    Dice d;
    Data(int y0, int x0, const Dice& d0){
        y = y0;
        x = x0;
        d = d0;
    }
    int toInt() const{
        return ((y * 14 + x) * 6 + d.pip[0]) * 6 + d.pip[1];
    }
    bool operator<(const Data& d) const{
        return toInt() < d.toInt();
    }
};

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

int main()
{
    int h, w;
    cin >> h >> w;

    vector<string> s(h+2, string(w+2, '.'));
    for(int i=1; i<=h; ++i){
        for(int j=1; j<=w; ++j){
            cin >> s[i][j];
        }
    }
    h += 2;
    w += 2;

    vector<string> face(6);
    for(int i=0; i<6; ++i)
        cin >> face[i];

    int sy, sx, gy, gx;
    cin >> sy >> sx >> gy >> gx;

    Dice init;
    init.pip[0] = 4;
    init.pip[1] = 3;
    init.pip[2] = 2;
    init.pip[3] = 1;
    init.pip[4] = 0;
    init.pip[5] = 5;

    vector<bool> check(14*14*6*6, false);
    queue<Data> q;
    for(int i=0; i<24; ++i){
        init.roll(xor128() % 6);
        Data d(gy, gx, init);
        if(!check[d.toInt()]){
            check[d.toInt()] = true;
            q.push(d);
        }else{
            -- i;
        }
    }

    vector<vector<Data> > edges(14*14*6*6);
    while(!q.empty()){
        Data d0 = q.front();
        q.pop();
        int y0 = d0.y;
        int x0 = d0.x;
        Dice dice0 = d0.d;

        for(int i=0; i<4; ++i){
            int y = y0 + dy[i];
            int x = x0 + dx[i];
            if(s[y][x] != '+'){
                if(i == 0 && s[y][x] != '-' && s[y][x] != '<')
                    continue;
                if(i == 1 && s[y][x] != '|' && s[y][x] != '^')
                    continue;
                if(i == 2 && s[y][x] != '-' && s[y][x] != '>')
                    continue;
                if(i == 3 && s[y][x] != '|' && s[y][x] != 'v')
                    continue;
            }

            Dice dice = dice0;
            dice.roll(i);
            Data d(y, x, dice);

            edges[d.toInt()].push_back(d0);
            if(!check[d.toInt()]){
                check[d.toInt()] = true;
                q.push(d);
            }
        }
    }

    while(init.pip[4] != 0 || init.pip[0] != 4)
        init.roll(xor128() % 6);
    Data d(sy, sx, init);
    if(edges[d.toInt()].size() == 0){
        cout << "no" << endl;
        return 0;
    }

    set<pair<Data, int> > curr;
    curr.insert(make_pair(d, 0));

    string ret;
    for(int i=0; i<42000; ++i){
        char c = 'a';
        for(set<pair<Data, int> >::iterator it=curr.begin(); it!=curr.end(); ++it){
            Data d = it->first;
            int i = d.d.pip[4];
            int j = it->second;
            c = min(c, face[i][j]);
        }

        ret += c;

        set<pair<Data, int> > next;
        for(set<pair<Data, int> >::iterator it=curr.begin(); it!=curr.end(); ++it){
            Data d = it->first;
            int i = d.d.pip[4];
            int j = it->second;
            if(c == face[i][j]){
                if(j == face[i].size() - 1){
                    if(d.y == gy && d.x == gx){
                        cout << ret << endl;
                        return 0;
                    }

                    for(unsigned k=0; k<edges[d.toInt()].size(); ++k){
                        Data d2 = edges[d.toInt()][k];
                        next.insert(make_pair(d2, 0));
                    }
                }else{
                    next.insert(make_pair(d, j+1));
                }
            }
        }

        curr.swap(next);
    }

    cout << "infinite" << endl;
    return 0;
}

Measured memory_bytes: 5756