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++: //#line 2 "SubstringQueries.cpp"

#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <random>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
#include <cstdint>
using namespace std;
using LL = long long;

int H, W;
vector<string>B;
bool flag[123][123];

int main() {
	cin >> H >> W;
	for (int i = 0; i < H; ++i) {
		string s;
		cin >> s;
		B.push_back(s);
	}
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			if (i % 2 && j % 2) {
			}
			else if (i % 2 == 0 && j % 2 == 0) {
				if ((i + j) % 4 == 0 && B[i][j] != '6') {
					B[i][j] = '#';
				}
				if ((i + j) % 4 == 2 && B[i][j] != '1') {
					B[i][j] = '#';
				}
			}
			else if (i % 2) {
				if (i % 4 == 1 && B[i][j] != '2') {
					B[i][j] = '#';
				}
				if (i % 4 == 3 && B[i][j] != '5') {
					B[i][j] = '#';
				}
			}
			else if (j % 2) {
				if (j % 4 == 1 && B[i][j] != '3') {
					B[i][j] = '#';
				}
				if (j % 4 == 3 && B[i][j] != '4') {
					B[i][j] = '#';
				}
			}
		}
	}
	queue<pair<int, int>>que;
	que.push({ 0,0 });
	flag[0][0] = true;
	int dx[4] = { 0,1,0,-1 };
	int dy[4] = { 1,0,-1,0 };
	while (!que.empty()) {
		int i = que.front().first;
		int j = que.front().second;
		que.pop();
		for (int d = 0; d < 4; ++d) {
			int ii = i + dx[d];
			int jj = j + dy[d];
			if (ii < 0 || jj < 0 || ii >= H || jj >= W)continue;
			if (B[ii][jj] != '#' && !flag[ii][jj]) {
				que.push({ ii,jj });
				flag[ii][jj] = true;
			}
		}
	}
	cout << (flag[H - 1][W - 1] ? "YES" : "NO") << endl;
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef pair<int, int> P;
typedef long long ll;
bool dp[110][110];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};
vector<string> tugi = {
    "6314",
    "2#2#",
    "1364",
    "5#5#"
};
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int h, w;
    cin >> h >> w;
    vector<string> s(h);
    rep(i, h)
    {
        cin >> s[i];
    }
    dp[0][0] = true;
    queue<P> que;
    que.push(P(0, 0));
    while (!que.empty())
    {
        P p = que.front();
        que.pop();
        for (int i = 0; i < 4; i++)
        {
            if (p.first + dx[i] < 0 || p.first + dx[i] >= w)
            {
                continue;
            }
            if (p.second + dy[i] < 0 || p.second + dy[i] >= h)
            {
                continue;
            }
            if (s[p.second + dy[i]][p.first + dx[i]] == '#')
            {
                continue;
            }
            if (dp[p.second + dy[i]][p.first + dx[i]])
            {
                continue;
            }
            int val = s[p.second + dy[i]][p.first + dx[i]] - '0';
            int now = s[p.second][p.first] - '0';
            char c = tugi[(p.second + dy[i])%4][(p.first + dx[i])%4];
            if (val != c-'0')
            {
                continue;
            }
            dp[p.second + dy[i]][p.first + dx[i]] = true;
            que.push(P(p.first + dx[i], p.second + dy[i]));
        }
    }
    if (dp[h - 1][w - 1])
    {
        cout << "YES" << endl;
    }
    else
    {
        cout << "NO" << endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

#define ll long long

const ll MOD = 998244353;
int h, w;
vector<string> sq;
bool ans = false;

// state[0] = 上
// state[1] = 手前
// state[2] = 右
// state[3] = 左
// state[4] = 奥
// state[5] = 下

int used[101][101];

void dfs(vector<char> state, int x, int y) {
  if (used[x][y] == 1) { return; }
  used[x][y] = 1;
  if (x == h - 1 && y == w - 1) {
    ans = true;
    return;
  }
  if (y - 1 >= 0) {
    if (sq[x][y - 1] == state[3]) {
      dfs({state[2], state[1], state[5], state[0], state[4], state[3]}, x,
          y - 1);
    }
  }
  if (x - 1 >= 0) {
    if (sq[x - 1][y] == state[4]) {
      dfs({state[1], state[5], state[2], state[3], state[0], state[4]}, x - 1,
          y);
    }
  }
  if (y + 1 < w) {
    if (sq[x][y + 1] == state[2]) {
      dfs({state[3], state[1], state[0], state[5], state[4], state[2]}, x,
          y + 1);
    }
  }
  if (x + 1 < h) {
    if (sq[x + 1][y] == state[1]) {
      dfs({state[4], state[0], state[2], state[3], state[5], state[1]}, x + 1,
          y);
    }
  }
}

signed main() {

  cin >> h >> w;
  sq.resize(h);
  vector<char> state(6);
  for (int i = 0; i < 6; i += 1) {
    state[i] = char(int('1') + i);
  }
  for (int i = 0; i < h; i += 1) {
    cin >> sq[i];
  }
  dfs(state, 0, 0);
  if (ans) {
    cout << "YES" << endl;
  } else {
    cout << "NO" << endl;
  }
}