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>
using namespace std;

int H, W;
string s[100];
bool vis[100][100];
bool dfs(int x, int y) {
    if (x == H-1 && y == W-1) return true;
    vis[x][y] = true;
    const int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
    for (int i = 0; i < 4; i++) {
        int u = x + dx[i], v = y + dy[i];
        if (0 <= u && u < H && 0 <= v && v < W
            && s[u][v] != '#' && !vis[u][v] && dfs(u, v))
            return true;
    }
    return false;
}

int main() {
    cin >> H >> W;
    for (int i = 0; i < H; i++) cin >> s[i];
    const string req[4] = {"6314", "2020", "1364", "5050"};
    for (int i = 0; i < H; i++)
        for (int j = 0; j < W; j++)
            if (s[i][j] != req[i%4][j%4]) s[i][j] = '#';
    cout << (dfs(0, 0) ? "YES\n" : "NO\n");
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <math.h>
#include <map>
#include <numeric>
#include <string>
#include <queue>
using namespace std;
typedef long long int ll;

bool can[101][101];

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

int num[6][2][4]=
{{{2,5,4,3},{5,2,3,4}},
{{1,6,3,4},{6,1,4,3}},
{{2,5,1,6},{5,2,6,1}},
{{2,5,6,1},{5,2,1,6}},
{{1,6,4,3},{6,1,3,4}},
{{2,5,3,4},{5,2,4,3}}
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int h,w; cin >> h >> w;
    char fi[h][w];
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            cin >> fi[i][j];
        }
    }
    can[0][0]=1;
    queue<pair<pair<int,int>,pair<int,int>>> q;
    q.push(make_pair(make_pair(0,0),make_pair(6,0)));
    while(q.size()){
        auto p=q.front(); q.pop();
        int x=p.first.first,y=p.first.second;
        for(int i=0;i<4;i++){
            int nx=dx[i]+x,ny=dy[i]+y;
            if(0<=nx&&nx<h&&0<=ny&&ny<w){
                if(can[nx][ny])continue;
                if(fi[nx][ny]=='#')continue;
                if(fi[nx][ny]-'0'!=num[p.second.first-1][p.second.second][i])continue;
                can[nx][ny]=1;
                int v=fi[x][y]-'0';
                int w=fi[nx][ny]-'0';
                int t=0;
                if(i==0||i==1){
                    if(v>=4&&i==1)t=1;
                    if(v<=3&&i==0)t=1;
                }
                else{
                    if(num[p.second.first-1][p.second.second][0]>=4)t=1;
                }
                q.push(make_pair(make_pair(nx,ny),make_pair(fi[nx][ny]-'0',t)));
            }
        }
    }
    if(can[h-1][w-1]){
        cout << "YES" << endl;
    }else{
        cout << "NO" << endl;
    }
}

C++: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int INF = (1<<25);
const ll INFLL = (1ll<<60);
const ll MOD = (ll)(1e9+7);

#define l_ength size

void mul_mod(ll& a, ll b){
	a *= b;
	a %= MOD;
}

void add_mod(ll& a, ll b){
	a = (a<MOD)?a:(a-MOD);
	b = (b<MOD)?b:(b-MOD);
	a += b;
	a = (a<MOD)?a:(a-MOD);
}

struct vtx{
	int x,y,f,r;
};

string s[111];
int h,w;

queue<vtx> que;

bool check(int i, int j){
	return (0<=i && i<h && 0<=j && j<w && s[i][j]!='#');
}

bool dist[111][111][6][6];

int main(void){
	int i,j;
	vtx u,v;
	cin >> h >> w;
	for(i=0; i<h; ++i){
		cin >> s[i];
		for(j=0; j<w; ++j){
			if(s[i][j]!='#'){
				s[i][j] -= '1';
			}
		}
	}
	dist[0][0][1][2] = true;
	v.x = 0; v.y = 0; v.f = 1; v.r = 2;
	que.push(v);
	while(!que.empty()){
		u = que.front();
		que.pop();
		i = u.x; j = u.y;
		if(i==(h-1)&&j==(w-1)){
			cout << "YES" << endl;
			return 0;
		}
		if(check(i-1,j)){
			if((!dist[i-1][j][s[i][j]][u.r]) && s[i-1][j]==(5-u.f)){
				dist[i-1][j][s[i][j]][u.r] = true;
				v.x = i-1; v.y = j; v.f = s[i][j]; v.r = u.r;
				que.push(v);
			}
		}
		if(check(i+1,j)){
			if((!dist[i+1][j][5-s[i][j]][u.r]) && s[i+1][j]==u.f){
				dist[i+1][j][5-s[i][j]][u.r] = true;
				v.x = i+1; v.y = j; v.f = 5-s[i][j]; v.r = u.r;
				que.push(v);
			}
		}
		if(check(i,j-1)){
			if((!dist[i][j-1][u.f][s[i][j]]) && s[i][j-1]==5-u.r){
				dist[i][j-1][u.f][s[i][j]] = true;
				v.x = i; v.y = j-1; v.f = u.f; v.r = s[i][j];
				que.push(v);
			}
		}
		if(check(i,j+1)){
			if((!dist[i][j+1][u.f][5-s[i][j]]) && s[i][j+1]==u.r){
				dist[i][j+1][u.f][5-s[i][j]] = true;
				v.x = i; v.y = j+1; v.f = u.f; v.r = 5-s[i][j];
				que.push(v);
			}
		}
	}
	cout << "NO" << endl;
	return 0;
}