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;
typedef long long ll;
//#include <boost/multiprecision/cpp_ll.hpp>
//typedef boost::multiprecision::cpp_ll ll;
typedef long double dd;
#define i_7 (ll)(1E9+7)
//#define i_7 998244353
#define i_5 i_7-2
ll mod(ll a){
    ll c=a%i_7;
    if(c>=0)return c;
    return c+i_7;
}
typedef pair<ll,ll> l_l;
ll inf=(ll)1E16;
#define rep(i,l,r) for(ll i=l;i<=r;i++)
#define pb push_back
ll max(ll a,ll b){if(a<b)return b;else return a;}
ll min(ll a,ll b){if(a>b)return b;else return a;}
void Max(ll &pos,ll val){pos=max(pos,val);}//Max(dp[n],dp[n-1]);
void Min(ll &pos,ll val){pos=min(pos,val);}
void Add(ll &pos,ll val){pos=mod(pos+val);}
dd EPS=1E-9;
string alp="abcdefghijklmnopqrstuvwxyz";
//#define endl "/n"
#define fastio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
struct sai{
    ll ue,mae,migi;
};
int main(){
    ll h,w;cin>>h>>w;
    string st[h];
    rep(i,0,h-1)cin>>st[i];
    bool b[h][w];
    rep(i,0,h-1){
        rep(j,0,w-1){
            b[i][j]=false;
        }
    }
    b[0][0]=true;
    queue<pair<sai,l_l>> q;
    sai s;
    s.ue=1;s.migi=3;s.mae=2;
    q.push(make_pair(s,make_pair(0,0)));
    while(q.size()>0){
        pair<sai,l_l> p=q.front();q.pop();
        s=p.first;
        sai sa;
        ll x=p.second.first;ll y=p.second.second;
        //cout<<x<<' '<<y<<endl;
        if(x>0){
            if(st[x-1][y]!='#' && b[x-1][y]==false){
                if(7-s.mae==st[x-1][y]-'0'){
                    b[x-1][y]=true;
                    sa.ue=s.mae;
                    sa.mae=7-s.ue;
                    sa.migi=s.migi;
                    q.push(make_pair(sa,make_pair(x-1,y)));
                }
            }
        }
        if(y>0){
            if(st[x][y-1]!='#' && b[x][y-1]==false){
                if(7-s.migi==st[x][y-1]-'0'){
                    b[x][y-1]=true;
                    sa.ue=s.migi;
                    sa.mae=s.mae;
                    sa.migi=7-s.ue;
                    q.push(make_pair(sa,make_pair(x,y-1)));
                }
            }
        }
        if(x<h-1){
            if(st[x+1][y]!='#' && b[x+1][y]==false){
                if(s.mae==st[x+1][y]-'0'){
                    b[x+1][y]=true;
                    sa.ue=7-s.mae;
                    sa.mae=s.ue;
                    sa.migi=s.migi;
                    q.push(make_pair(sa,make_pair(x+1,y)));
                }
            }
        }
        if(y<w-1){
            if(st[x][y+1]!='#' && b[x][y+1]==false){
                if(s.migi==st[x][y+1]-'0'){
                    b[x][y+1]=true;
                    sa.ue=7-s.migi;
                    sa.mae=s.mae;
                    sa.migi=s.ue;
                    q.push(make_pair(sa,make_pair(x,y+1)));
                }
            }
        }
    }
    if(b[h-1][w-1]){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }
    
    
    return 0;
}

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

signed main(){

  int h,w;
  cin>>h>>w;
  vector<string> s(h);
  for(auto& si:s)cin>>si;

  vector<vector<int>> a(h,vector<int>(w));
  for(int i=0;i<h;++i)for(int j=0;j<w;++j){
    if(s[i][j]=='#')continue;
    a[i][j] = (s[i][j]-'0');
  }

  struct dice{
    int sita,ue,migi,hidari,temae,oku;
    dice(){}
    dice order(int x){
      if(x==1){
        return to_migi();
      }
      if(x==4){
        return to_oku();
      }
      if(x==3){
        return to_hidari();
      }
      if(x==2){
        return to_temae();
      }
      return *this;
    }
    dice to_migi(){
      dice nxt = *this;
      nxt.sita = migi;
      nxt.ue = hidari;
      nxt.migi = ue;
      nxt.hidari = sita;
      return nxt;
    }
    dice to_hidari(){
      dice nxt = *this;
      nxt.sita = hidari;
      nxt.ue = migi;
      nxt.hidari = ue;
      nxt.migi = sita;
      return nxt;
    }
    dice to_oku(){
      dice nxt = *this;
      nxt.sita = oku;
      nxt.ue = temae;
      nxt.temae = sita;
      nxt.oku = ue;
      return nxt;
    }
    dice to_temae(){
      dice nxt = *this;
      nxt.sita = temae;
      nxt.ue = oku;
      nxt.temae = ue;
      nxt.oku = sita;
      return nxt;
    }
    
  };

  dice d;
  d.sita = 6;
  d.ue = 1;
  d.migi = 3;
  d.hidari = 4;
  d.temae = 2;
  d.oku = 5;

  using T = tuple<int,int,dice>;
  queue<T> que;
  que.emplace(0,0,d);
  vector<vector<int>> visited(h,vector<int>(w,0));
  constexpr int dx[]={1,0,-1,0,1,1,-1,-1};
  constexpr int dy[]={0,1,0,-1,1,-1,1,-1};
  constexpr int dd[]={1,2,3,4};
  while(!que.empty()){
    int y,x;
    dice d;
    tie(y,x,d) = que.front();
    que.pop();
    if(visited[y][x])continue;
    visited[y][x] = 1;
    for(int i=0;i<4;++i){
      int ny = y+dy[i];
      int nx = x+dx[i];
      if(ny==h||nx==w||ny==-1||nx==-1)continue;
      if(s[ny][nx]=='#')continue;
      dice nxt = d.order(dd[i]);
      if(nxt.sita==a[ny][nx])que.emplace(ny,nx,nxt);
    }
  }
  cout<<(visited[h-1][w-1]?"YES":"NO")<<endl;

}