using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Math;

public static class P
{
    public static void Main()
    {
        var hw = Console.ReadLine().Split().Select(int.Parse).ToArray();
        var map = Enumerable.Repeat(0, hw[0]).Select(_ => Console.ReadLine().Select(x => x - '0').ToArray()).ToArray();
        HashSet<int>[][] arrivedStates = Enumerable.Range(0, hw[0]).Select(_ => Enumerable.Range(0, hw[1]).Select(__ => new HashSet<int>()).ToArray()).ToArray();
        var initDice = new Dice(false);
        Queue<Tuple<Dice, Tuple<int, int>>> dices = new Queue<Tuple<Dice, Tuple<int, int>>>();
        dices.Enqueue(new Tuple<Dice, Tuple<int, int>>(initDice, new Tuple<int, int>(0, 0)));
        arrivedStates[0][0].Add(initDice.Hash);
        while (dices.Count > 0)
        {
            var elem = dices.Dequeue();
            var dice = elem.Item1;
            var y = elem.Item2.Item1;
            var x = elem.Item2.Item2;
            if (y != 0)
            {
                var newDice = dice;
                newDice.Up();
                if (!arrivedStates[y - 1][x].Contains(newDice.Hash) && newDice.bottom == map[y - 1][x])
                {
                    arrivedStates[y - 1][x].Add(newDice.Hash);
                    dices.Enqueue(new Tuple<Dice, Tuple<int, int>>(newDice, new Tuple<int, int>(y - 1, x)));
                }
            }
            if (y != hw[0] - 1)
            {
                var newDice = dice;
                newDice.Down();
                if (!arrivedStates[y + 1][x].Contains(newDice.Hash) && newDice.bottom == map[y + 1][x])
                {
                    arrivedStates[y + 1][x].Add(newDice.Hash);
                    dices.Enqueue(new Tuple<Dice, Tuple<int, int>>(newDice, new Tuple<int, int>(y + 1, x)));
                }
            }
            if (x != 0)
            {
                var newDice = dice;
                newDice.Left();
                if (!arrivedStates[y][x - 1].Contains(newDice.Hash) && newDice.bottom == map[y][x - 1])
                {
                    arrivedStates[y][x - 1].Add(newDice.Hash);
                    dices.Enqueue(new Tuple<Dice, Tuple<int, int>>(newDice, new Tuple<int, int>(y, x - 1)));
                }
            }
            if (x != hw[1] - 1)
            {
                var newDice = dice;
                newDice.Right();
                if (!arrivedStates[y][x + 1].Contains(newDice.Hash) && newDice.bottom == map[y][x + 1])
                {
                    arrivedStates[y][x + 1].Add(newDice.Hash);
                    dices.Enqueue(new Tuple<Dice, Tuple<int, int>>(newDice, new Tuple<int, int>(y, x + 1)));
                }
            }
        }

        Console.WriteLine(arrivedStates[hw[0] - 1][hw[1] - 1].Count != 0 ? "YES" : "NO");
    }
}

struct Dice
{
    public int top;
    public int oku;
    public int right;
    public int temae;
    public int left;
    public int bottom;
    public int Hash => top * 100000 + oku * 10000 + right * 1000 + temae * 100 + left * 10 + bottom;
    public Dice(bool b)
    {
        top = 1;
        oku = 5;
        right = 3;
        temae = 2;
        left = 4;
        bottom = 6;
    }
    public void Up()
    {
        var temp = top;
        top = temae;
        temae = bottom;
        bottom = oku;
        oku = temp;
    }
    public void Left()
    {
        var temp = top;
        top = right;
        right = bottom;
        bottom = left;
        left = temp;
    }
    public void Right()
    {
        var temp = top;
        top = left;
        left = bottom;
        bottom = right;
        right = temp;
    }
    public void Down()
    {
        var temp = top;
        top = oku;
        oku = bottom;
        bottom = temae;
        temae = temp;
    }
}



Measured memory_bytes: 21108