/*
さいころ

mapを使っているところは普通のサイコロとかなら配列で大丈夫
まぁ、せいぜいO(log24)なのでOKか

参考:
http://www.prefield.com/algorithm/misc/dice.html
参考:
https://onlinejudge.u-aizu.ac.jp/beta/review.html#KUPC2020Spring/4276858
verify:
https://onlinejudge.u-aizu.ac.jp/beta/room.html#KUPC2020Spring/workspace
*/
#include <bits/stdc++.h>
using namespace std;

//up(上),down(下),front(前),back(後ろ),right(右),left(左)
enum FACE{UP,DOWN,FRONT,BACK,RIGHT,LEFT};
template<typename T>
struct Dice{
    T var[6];
    T& operator[](FACE f){return var[f];}

    void rollR(){roll(UP,LEFT,DOWN,RIGHT);}
    void rollL(){roll(UP,RIGHT,DOWN,LEFT);}
    void rollU(){roll(UP,FRONT,DOWN,BACK);}
    void rollD(){roll(UP,BACK,DOWN,FRONT);}
    void rollT(){roll(FRONT,RIGHT,BACK,LEFT);}
    void rollH(){roll(FRONT,LEFT,BACK,RIGHT);}
    void roll(FACE a,FACE b,FACE c,FACE d){
        int tmp=var[a];
        var[a]=var[b];
        var[b]=var[c];
        var[c]=var[d];
        var[d]=tmp;
    }
    bool operator==(const Dice &d)const noexcept{
        for(int i=0;i<6;i++){
            if(var[i]!=d.var[i]) return false;
        }
        return true;
    }

};

template<typename T>
struct allDice{
    using ptt=pair<T,T>;
    map<ptt,int> M;
    vector<Dice<T>> V;

    allDice(Dice<T> d){
        int cnt=0;
        V.resize(24);
        for(int k=0;k<6;(k&1?d.rollR():d.rollD()),k++){
            for(int i=0;i<4;d.rollT(),i++,cnt++){
                V[cnt]=d;
                M[ptt(d[UP],d[FRONT])]=cnt;
            }
        }
    }
    Dice<T> operator[](int idx){return V[idx];};

    Dice<T> find(T up,T front){return V[ M[ptt(up,front)] ];}

    Dice<T> find(FACE f,T a,FACE g,T b){
        for(int i=0;i<24;i++){
            if(V[i][f]==a && V[i][g]==b) return V[i];
        }
    }

    int id(Dice<T> &d){return M[ptt(d[UP],d[FRONT])];}

};

signed main(){
    int H,W;
    cin>>H>>W;
    Dice<int> d;
    d[UP]=1; d[DOWN]=6; d[RIGHT]=3; d[LEFT]=4; 
    d[FRONT]=2; d[BACK]=5;
    allDice<int> D(d);
    queue<tuple<int,int,int>> que;
    char S[110][110];
    bool flag[110][110][24];
    for(int i=0;i<110;i++){
        for(int j=0;j<110;j++){
            for(int k=0;k<24;k++){
                flag[i][j][k]=false;
            }
        }
    }
    for(int i=1;i<=H;i++){
        for(int j=1;j<=W;j++) cin>>S[i][j];
    }
    que.emplace(1,1,D.id(d));
    flag[1][1][D.id(d)]=true;
    while(!que.empty()){
        int h,w,id;
        tie(h,w,id)=que.front(); que.pop();
        auto d=D[id];
        auto r=d; r.rollR();
        auto l=d; l.rollL();
        auto dow=d; dow.rollD();
        auto u=d; u.rollU();
        if(r[DOWN]==(int)(S[h][w+1]-'0')){
            if(!flag[h][w+1][D.id(r)]) que.emplace(h,w+1,D.id(r)),flag[h][w+1][D.id(r)]=true;
        }
        if(l[DOWN]==(int)(S[h][w-1]-'0')){
            if(!flag[h][w-1][D.id(l)]) que.emplace(h,w-1,D.id(l)),flag[h][w-1][D.id(l)]=true;
        }
        if(dow[DOWN]==(int)(S[h+1][w]-'0')){
            if(!flag[h+1][w][D.id(dow)]) que.emplace(h+1,w,D.id(dow)),flag[h+1][w][D.id(dow)]=true;
        }
        if(u[DOWN]==(int)(S[h-1][w]-'0')){
            if(!flag[h-1][w][D.id(u)]) que.emplace(h-1,w,D.id(u)),flag[h-1][w][D.id(u)]=true;
        }
        
    }
    for(int i=0;i<24;i++){
        if(flag[H][W][i]){
            cout<<"YES"<<endl;
            return 0;
        }
    }
    cout<<"NO"<<endl;
}


Measured memory_bytes: 3456