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++: #define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())


class Dice {
public:
	int top, front, r;
	Dice() :top(1), front(2), r(3) {}
	Dice(int a, int b,int c) :top(a), front(b), r(c) {}
	void north() {
		int a = top;
		top = front;
		front = 7 - a;
	}
	void east() {
		int a = top;
		top = 7 - r;
		r = a;
	}
	void west() {
		int a = top;
		top = r;
		r = 7 - a;
	}
	void south() {
		int a = top;
		top = 7 - front;
		front = a;
	}
	void right() {
		int a = front;
		front = r;
		r = 7 - a;
	}
	void left() {
		int a = front;
		front = 7 - r;
		r = a;
	}
};


char f[100][100];

bool vis[100][100][6][6][6];


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int h, w;
	cin >> h >> w;
	rep(i, h)rep(j, w)cin >> f[i][j];

	queue<tuple<int, int, int, int, int>> q;
	vis[0][0][5][1][2] = true;
	q.emplace(0, 0, 5, 1, 2);

	string ans = "NO";

	while (!q.empty()) {
		auto t = q.front();
		q.pop();

		int y, x, soko, fr, ri;
		tie(y, x, soko, fr, ri) = t;
		Dice dice(7 - (soko + 1), fr + 1, ri + 1);

		if (y==h-1 && x==w-1) {
			ans = "YES";
			break;
		}

		if (0 < y) {
			Dice d = dice;
			d.north();
			if (f[y - 1][x] - '0' == 7 - d.top && !vis[y - 1][x][7 - d.top - 1][d.front - 1][d.r - 1]) {
				vis[y - 1][x][7 - d.top - 1][d.front - 1][d.r - 1] = true;
				q.emplace(y - 1, x, 7 - d.top - 1, d.front - 1, d.r - 1);
			}
		}
		if (y + 1< h) {
			Dice d = dice;
			d.south();
			if (f[y + 1][x] - '0' == 7 - d.top && !vis[y + 1][x][7 - d.top - 1][d.front - 1][d.r - 1]) {
				vis[y + 1][x][7 - d.top - 1][d.front - 1][d.r - 1] = true;
				q.emplace(y + 1, x, 7 - d.top - 1, d.front - 1, d.r - 1);
			}
		}
		if (0 < x) {
			Dice d = dice;
			d.west();
			if (f[y][x - 1] - '0' == 7 - d.top && !vis[y][x - 1][7 - d.top - 1][d.front - 1][d.r - 1]) {
				vis[y][x - 1][7 - d.top - 1][d.front - 1][d.r - 1] = true;
				q.emplace(y, x - 1, 7 - d.top - 1, d.front - 1, d.r - 1);
			}
		}
		if (x + 1 < w) {
			Dice d = dice;
			d.east();
			if (f[y][x + 1] - '0' == 7 - d.top && !vis[y][x + 1][7 - d.top - 1][d.front - 1][d.r - 1]) {
				vis[y][x + 1][7 - d.top - 1][d.front - 1][d.r - 1] = true;
				q.emplace(y, x + 1, 7 - d.top - 1, d.front - 1, d.r - 1);
			}
		}
	}

	cout << ans << endl;


	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
#define dbg(x...) do { cout << "\033[32;1m " << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<template<typename...> class T, typename t, typename... A>
void err(T<t> a, A... x) { for (auto v: a) cout << v << ' '; err(x...); }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
#else
#define dbg(...)
#endif
typedef long long ll;
typedef pair<int,int> pi;
typedef vector<int> vi;
template<class T> using vc=vector<T>;
template<class T> using vvc=vc<vc<T>>;
template<class T> void mkuni(vector<T>&v)
{
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}
ll rand_int(ll l, ll r) //[l, r]
{
    static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(gen);
}
template<class T>
void print(T x,int suc=1)
{
    cout<<x;
    if(suc==1) cout<<'\n';
    else cout<<' ';
}
template<class T>
void print(const vector<T>&v,int suc=1)
{
    for(int i=0;i<v.size();i++)
    print(v[i],i==(int)(v.size())-1?suc:2);
}
const int maxn=105;
string maze[maxn];
bool vis[maxn][maxn][7][7];
int h,w;
bool dfs(int x,int y,int up=1,int ft=2,int bt=6,int bk=5,int lf=4,int rt=3)
{
    if(x<0||x>=h||y<0||y>=w) return false;
    if(vis[x][y][up][ft]||maze[x][y]=='#'||maze[x][y]-'0'!=bt) return false;
    if(x==h-1&&y==w-1) return true;
    vis[x][y][up][ft]=1;
    assert(up+bt==7&&ft+bk==7&&lf+rt==7);
    bool ret=0;
    ret|=dfs(x+1,y,bk,up,ft,bt,lf,rt);
    ret|=dfs(x-1,y,ft,bt,bk,up,lf,rt);
    ret|=dfs(x,y+1,lf,ft,rt,bk,bt,up);
    ret|=dfs(x,y-1,rt,ft,lf,bk,up,bt);
    return ret;
}
int main()
{
    cin>>h>>w;
    for(int i=0;i<h;i++) cin>>maze[i];
    if(dfs(0,0)) cout<<"YES\n";
    else cout<<"NO\n";
}

C++: #include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(int)(a); (i)<(int)(b); ++(i))
#define rFor(i, a, b) for(int (i)=(int)(a)-1; (i)>=(int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template<class T> bool chmax(T &a, const T &b){if(a<b){a=b; return true;} return false;}
template<class T> bool chmin(T &a, const T &b){if(a>b){a=b; return true;} return false;}
template<class T> T div_floor(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>=0 ? a/b : (a+1)/b-1;
}
template<class T> T div_ceil(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>0 ? (a-1)/b+1 : a/b;
}

constexpr lint mod = 1e9+7;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

int h, w;
char c[110][110];
string s[4] = {"6314", "2020", "1364", "5050"};
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
bool used[110][110];

void dfs(int x, int y){
    if(used[x][y]) return;
    used[x][y] = true;
    rep(i, 4){
        int nx = x+dx[i], ny = y+dy[i];
        if(0<=nx && nx<100 && 0<=ny && ny<100){
            if(c[x][y] == s[x%4][y%4] && c[nx][ny] == s[nx%4][ny%4]){
                dfs(nx, ny);
            }
        }
    }
}

int main(){
    scanf("%d%d", &h, &w);
    rep(i, 100)rep(j, 100) c[i][j] = '/';
    rep(i, h)rep(j, w) scanf(" %c", &c[i][j]);
    rep(i, 100)rep(j, 100) used[i][j] = false;
    dfs(0, 0);
    puts(used[h-1][w-1] ? "YES" : "NO");
}