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

#define rep(i, n) for(int i = 0; i < (n); ++i)
#define repr(i, n) for(int i = (n-1); i >= 0; --i)

typedef long long ll;
typedef pair<int, int> P;

const int MAX = 200005;
const int INF = 1001001001;
const int MOD = 1000000007;

struct dice {
    int front, right, bottom;
    dice(){
        front = 2;
        right = 3;
        bottom = 6;
    }
    void b() {
        int tmp = front;
        front = bottom;
        bottom = 7 - tmp;
    }
    void f() {
        int tmp = bottom;
        bottom = front;
        front = 7 - tmp;
    }
    void l() {
        int tmp = right;
        right = bottom;
        bottom = 7 - tmp;
    }
    void r() {
        int tmp = bottom;
        bottom = right;
        right = 7 - tmp;
    }
};

int main(){
    int H, W;
    cin >> H >> W;

    vector<string> IN(H);
    rep(i, H) cin >> IN[i];

    vector<vector<int>> S(H, vector<int>(W));
    rep(i, H)rep(j, W) {
        if (IN[i][j] != '#') S[i][j] = IN[i][j] - '0';
        else IN[i][j] = -1;
    }

    queue<pair<P, dice>> q;
    dice di;
    q.emplace(P(0, 0), di);
    vector<vector<bool>> used(H, vector<bool>(W));
    used[0][0] = true;
    bool ans = false;
    while (!q.empty()) {
        auto p = q.front(); q.pop();
        int i = p.first.first, j = p.first.second;
        dice d = p.second;
        if (i == H-1 && j == W-1) {
            ans = true;
            break;
        }
        if (i+1 < H && !used[i+1][j] && d.front == S[i+1][j]) {
            dice nd(d); nd.f();
            q.emplace(P(i+1, j), nd);
            used[i+1][j] = true;
        }
        if (j+1 < W && !used[i][j+1] && d.right == S[i][j+1]) {
            dice nd(d); nd.r();
            q.emplace(P(i, j+1), nd);
            used[i][j+1] = true;
        }
        if (i-1 >= 0 && !used[i-1][j]) {
            dice nd(d); nd.b();
            if (nd.bottom == S[i-1][j]) {
                q.emplace(P(i-1, j), nd);
                used[i-1][j] = true;
            }
        }
        if (j-1 >= 0 && !used[i][j-1]) {
            dice nd(d); nd.l();
            if (nd.bottom == S[i][j-1]) {
                q.emplace(P(i, j-1), nd);
                used[i][j-1] = true;
            }
        }
    }

    if (ans) puts("YES");
    else puts("NO");
}

C++: #include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <set>
#include <cmath>
#include <tuple>
#include <cstring>
#include <map>
#include <iomanip>
#include <ctime>
#include <complex>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define _ << " " <<
#define all(X) (X).begin(), (X).end()
#define len(X) (X).size()
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define Tiii tuple<int, int, int>
#define Tlll tuple<ll, ll, ll>
#define PI 3.14159265358979324

int h, w, dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
char s[105][105];
bool b[105][105] = {};

void dfs(int x, int y) {
    b[x][y] = 1;
    if (x == h - 1 && y == w - 1) return;
    
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx < 0 || nx >= h || ny < 0 || ny >= w) continue;
        if (!b[nx][ny] && s[nx][ny] >= '1' && s[nx][ny] <= '6') {
            dfs(nx, ny);
        }
    }
}

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

    for (int i =0 ; i < h; i++) cin >> s[i];

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (j % 2 == 0 && i % 2 == 0) {
                if ((i + j) % 4 == 0 && s[i][j] != '6') s[i][j] = '0';
                if ((i + j) % 4 == 2 && s[i][j] != '1') s[i][j] = '0';
            }
            else {
                if (j % 4 == 1) {
                    if (i % 2 == 0 && s[i][j] != '3') s[i][j] = '0';
                }
                if (j % 4 == 3) {
                    if (i % 2 == 0 && s[i][j] != '4') s[i][j] = '0';
                }
                if (i % 4 == 1) {
                    if (j % 2 == 0 && s[i][j] != '2') s[i][j] = '0';
                }
                if (i % 4 == 3) {
                    if (j % 2 == 0 && s[i][j] != '5') s[i][j] = '0';
                }
            }
        }
    }

    for (int i = 0; i < h; i++ ) {
        for (int j = 0; j < w; j++) {
            //cerr << s[i][j];
        }
        //cerr << endl;
    }

    dfs(0, 0);

    cout << (b[h-1][w-1] ? "YES" : "NO") << endl;

}