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 <bits/stdc++.h>
#define REP(i, n) for(int i = 0;i < n;i++)
#define ll long long
using namespace std;
//typedef vector<unsigned int>vec;
//typedef vector<ll>vec;
//typedef vector<vec> mat;
typedef pair<int, int> P;
typedef pair<ll,ll> LP;
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
const int INF = 1000000000;
const ll LINF = 1000000000000000000;//1e18
const ll  MOD = 1000000007;
const double PI = acos(-1.0);
const double EPS = 1e-10;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
//template<class T> inline void add(T &a, T b){a = ((a+b) % MOD + MOD) % MOD;};


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int H, W;
    cin >> H >> W;
    vector<string> fi(H);
    REP(i,H) cin >> fi[i];
    string ans = "NO";
    vector<int> dice(4);
    dice[0] = 2, dice[1] = 3, dice[2] = 5, dice[3] = 4;
    vector<vector<bool>> used(H, vector<bool>(W));

    auto dfs = [&](auto && self, int h, int w, vector<int> D) -> void{
        if(used[h][w]) return;
        used[h][w] = true;
        if(h == H-1 && w == W-1){
            ans = "YES";
            return;
        }
        REP(i,4){
            int nh = h + dx[i], nw = w + dy[i];
            if(nh < 0 || nh >= H || nw < 0 || nw >= W) continue;
            if(fi[nh][nw] == '#') continue;
            int next = fi[nh][nw] - '0';
            int d = D[i];
            // cout << nh << " " << nw << " " << next << " " << d << endl;
            // cout << "DICE : ";
            vector<int> dd = D;
            // REP(i,4) cout << D[i] << " ";
            // cout << endl;
            if(next != d) continue;
            int cur = fi[h][w] - '0';
            if(i == 0) dd[0] = 7 - cur, dd[2] = cur;
            else if(i == 1) dd[1] = 7 - cur,  dd[3] = cur;
            else if(i == 2) dd[0] = cur, dd[2] = 7 - cur;
            else dd[1] = cur, dd[3] = 7 - cur;
            self(self, nh, nw,dd);
        }
    };
    dfs(dfs, 0, 0, dice);
    cout << ans << endl;
}

C++: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const ll INF=1LL<<60;
int h,w;
const int nmax=102;
char c[nmax][nmax];
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
int p[4][6]={{1,5,2,3,0,4},{2,1,5,0,4,3},{3,1,0,5,4,2},{4,0,2,3,5,1}};
bool vis[nmax][nmax];
bool bfs(int i,int j,vector<int> a){
    vis[i][j]=true;
    if(i==h-1&&j==w-1){
        return true;
    }
    bool f=false;
    vector<int> r(6);
    for(int l=0;l<4;l++){
        int x=i+dx[l],y=j+dy[l];
        if(x<0||x>h-1||y<0||y>w-1){
            continue;
        }
        if(c[x][y]=='#'||vis[x][y]){
            continue;
        }
        if(c[x][y]-'0'==a[l+1]){
            for(int s=0;s<6;s++){
                r[s]=a[p[l][s]];
            }
            f=f|bfs(x,y,r);
        }
    }
    return f;
}
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> h >> w;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            cin >> c[i][j];
        }
    }
    vector<int> n(6);
    for(int i=0;i<6;i++){
        n[i]=6-i;
    }
    if(bfs(0,0,n)){
        cout << "YES" << endl;
    }
    else{
        cout << "NO" << endl;
    }
}

C++: #include <iostream>
#include <string>
#include <queue>
using namespace std;
typedef pair<int, int> P;

int main()
{
    int h, w;
    cin >> h >> w;
    string s[102];
    for(int i = 0; i < h; i++) cin >> s[i];
    bool used[102][102];
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++) used[i][j] = false;
    }
    queue<P> que;
    que.push(P(0, 0));
    while(que.size()){
        P p = que.front();
        que.pop();
        char r, l, f, b, u;
        if(p.first % 4){
            f = '2';
            b = '5';
        }
        else{
            f = '5';
            b = '2';
        }
        if(p.second % 4){
            r = '4';
            l = '3';
        }
        else{
            r = '3';
            l = '4';
        }
        if((p.first + p.second) % 4){
            u = '6';
        }
        else{
            u = '1';
        }
        if(p.first == h - 1 && p.second == w - 1){
            cout << "YES" << endl;
            return 0;
        }
        if(p.first == h - 1 && p.second == w - 2){
            if(s[p.first][p.second + 1] == r){
                cout << "YES" << endl;
                return 0;
            }
        }
        if(p.first == h - 2 && p.second == w - 1){
            if(s[p.first + 1][p.second] == b){
                cout << "YES" << endl;
                return 0;
            }
        }
        if(p.first + 2 < h && !used[p.first + 2][p.second] && 
           s[p.first + 1][p.second] == b && s[p.first + 2][p.second] == u){
            used[p.first + 2][p.second] = true;
            que.push(P(p.first + 2, p.second));
        }
        if(p.second + 2 < w && !used[p.first][p.second + 2] &&
           s[p.first][p.second + 1] == r && s[p.first][p.second + 2] == u){
            used[p.first][p.second + 2] = true;
            que.push(P(p.first, p.second + 2));
        }
        if(p.first - 2 >= 0 && !used[p.first - 2][p.second] &&
           s[p.first - 1][p.second] == f && s[p.first - 2][p.second] == u){
            used[p.first - 2][p.second] = true;
            que.push(P(p.first - 2, p.second));
        }
        if(p.second - 2 < w && !used[p.first][p.second - 2] &&
           s[p.first][p.second - 1] == l && s[p.first][p.second - 2] == u){
            used[p.first][p.second - 2] = true;
            que.push(P(p.first, p.second - 2));
        }
    }
    cout << "NO" << endl;
}