Go: package main

import "fmt"

var h, w int
var maze [][]byte

var visited [][]bool

type dice struct {
	top, bottom, right, left, up, down int
}

func move(d *dice, dir byte) {
	now := d.top
	switch dir {
	case 'N':
		d.top = d.down
		d.down = d.bottom
		d.bottom = d.up
		d.up = now
	case 'S':
		d.top = d.up
		d.up = d.bottom
		d.bottom = d.down
		d.down = now
	case 'W':
		d.top = d.right
		d.right = d.bottom
		d.bottom = d.left
		d.left = now
	case 'E':
		d.top = d.left
		d.left = d.bottom
		d.bottom = d.right
		d.right = now
	}
}

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

func dfs(x, y int, d *dice) bool {
	// fmt.Printf("dfs(%d,%d) en: dice.bottom=%d\n", x, y, d.bottom)
	visited[y][x] = true // (x,y)に到達した
	if (y == h-1) && (x == w-1) {
		return true
	}
	// 4方のマス目に進めるかどうかチェック
	for i := 0; i < 4; i++ {
		nx := x + dx[i]
		ny := y + dy[i]
		dir := []byte{'E', 'W', 'S', 'N'}
		dc := *d
		move(&dc, dir[i]) // 動かしてみる
		if 0 <= nx && nx < w && 0 <= ny && ny < h && maze[ny][nx] != '#' && !visited[ny][nx] && dc.bottom == int(maze[ny][nx]-'0') {
			// fmt.Printf("move dir %c, new bottom=%d, move to (nx, ny)=(%d,%d)\n", dir[i], dc.bottom, nx, ny)
			if dfs(nx, ny, &dc) {
				return true
			}
		} else {
			continue
		}
	}
	return false
}

func main() {
	fmt.Scan(&h, &w)
	maze = make([][]byte, h)
	visited = make([][]bool, h)
	for i := 0; i < h; i++ {
		visited[i] = make([]bool, w)
		maze[i] = make([]byte, w)
		fmt.Scan(&maze[i])
	}
	// fmt.Println("h", h, "w", w, "maze", maze)
	// visited[0][0] = true
	var d dice
	d.bottom = 6
	d.top = 1
	d.right = 3
	d.left = 4
	d.down = 2
	d.up = 5
	if dfs(0, 0, &d) {
		fmt.Println("YES")
	} else {
		fmt.Println("NO")
	}
}

C++: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef vector<P> vpl;
#define rep(i,n) for(ll i=0; i<(n); i++)
#define REP(i,a,b) for(ll i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 1020000;
ll dy[8] = {0,1,0,-1,1,-1,1,-1};
ll dx[8] = {1,0,-1,0,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){cout << a << " " << b << endl;}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << endl;
}
const int mod = 998244353;



typedef pair<P,vl> pp;
ll h,w;
char s[105][105];
map<pair<P,vl>,ll> f;

bool in(ll y, ll x){
	return 0 <= y && y < h && 0 <= x && x < w;
}

int main(){
	cin >> h >> w;
	rep(i,h) rep(j,w) cin >> s[i][j];
	queue<pp> q;
	vl t(6);
	t[0] = 6, t[1] = 1, t[2] = 2, t[3] = 3, t[4] = 5, t[5] = 4;
	f[pp(P(0,0),t)]++;
	q.emplace(P(0,0),t);
	while(!q.empty()){
		auto u = q.front(); q.pop();
		ll y = u.first.first;
		ll x = u.first.second;
		vl v = u.second;
		ll now = s[y][x] - '0';
		rep(i,4){
			ll ny = y + dy[i];
			ll nx = x + dx[i];
			if(s[ny][nx] == '#') continue;
			if(in(ny,nx)){
				vl nnxt(6);
				if(dy[i]==1){
					nnxt[0] = v[2];
					nnxt[1] = v[4];
					nnxt[2] = v[1];
					nnxt[3] = v[3];
					nnxt[4] = v[0];
					nnxt[5] = v[5];
				}else if(dy[i]==-1){
					nnxt[0] = v[4];
					nnxt[1] = v[2];
					nnxt[2] = v[0];
					nnxt[3] = v[3];
					nnxt[4] = v[1];
					nnxt[5] = v[5];
				}else if(dx[i]==1){
					nnxt[0] = v[3];
					nnxt[1] = v[5];
					nnxt[2] = v[2];
					nnxt[3] = v[1];
					nnxt[4] = v[4];
					nnxt[5] = v[0];
				}else if(dx[i]==-1){
					nnxt[0] = v[5];
					nnxt[1] = v[3];
					nnxt[2] = v[2];
					nnxt[3] = v[0];
					nnxt[4] = v[4];
					nnxt[5] = v[1];
				}
				ll nxt = s[ny][nx] - '0';
				if(nxt != nnxt[0]) continue;
				if(f.find(pp(P(ny,nx),nnxt)) == f.end()){
					f[pp(P(ny,nx),nnxt)]++;
					q.emplace(P(ny,nx),nnxt);
				}
			}
		}
	}
	bool flag = false;
	vl vv(6);
	rep(i,6) vv[i] = i+1;
	do{
		if(f.find(pp(P(h-1,w-1),vv)) != f.end()){
			flag = true;
			break;
		}
	}while(next_permutation(all(vv)));
	if(flag) puts("YES");
	else puts("NO");
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;

int h, w;
vector<string> s;
const int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1};
vector<vector<bool>> used;

bool dfs(int x, int y, int a, int b, int c, int d, int e, int f) {
    if (x == h - 1 && y == w - 1) {
        return true;
    }
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx < h && nx >= 0 && ny < w && ny >= 0 && !used[nx][ny]) {
            used[nx][ny] = true;
            if (i == 0) {// 前
                if (b != s[nx][ny] - '0') {
                    continue;
                }
                else if (dfs(nx, ny, e, a, c, d, f, b)) {
                    return true;
                }
            }
            else if (i == 1) {// 右
                if (c != s[nx][ny] - '0') {
                    continue;
                }
                else if (dfs(nx, ny, d, b, a, f, e, c)) {
                    return true;
                }
            }
            else if (i == 2) {// 後
                if (e != s[nx][ny] - '0') {
                    continue;
                }
                else if (dfs(nx, ny, b, f, c, d, a, e)) {
                    return true;
                }
            }
            else {// 左
                if (d != s[nx][ny] - '0') {
                    continue;
                }
                else if (dfs(nx, ny, c, b, f, a, e, d)) {
                    return true;
                }
            }
        }
    }
    //cout << x << " " << y << " " << a << " " << b << " " << c << endl;
    return false;
}

int main() {
    cin >> h >> w;
    s.resize(h);
    used.resize(h, vector<bool>(w, false));
    for (int i = 0; i < h; i++) {
        cin >> s[i];
    }
    used[0][0] = true;
    if (dfs(0, 0, 1, 2, 3, 4, 5, 6)) {
        puts("YES");
    }
    else {
        puts("NO");
    }
    return 0;
}