Problem:
宇宙人のメッセージ

宇宙人 Mr.X は地球への来星記念として、地球人に向けてのメッセージを残しました。 Mr.X がメッセージを残す場所に選んだのは古代遺跡として有名な"トロンコ遺跡"でした。 ここはいろいろな大きさの碁盤のマス目に、奇抜な石像が無造作に配置されている不思議な場所でした。

Mr.X は、メッセージとして、石像が置かれていない全てのマス目を一度だけ通る、単一の閉曲線を描きました。Mr.X はとても賢く、このような閉曲線を描くことが可能な碁盤であれば必ず閉曲線を描き、メッセージを残しました。しかし、石像の配置によっては、閉曲線を描くことが不可能な碁盤もあり、その場合はメッセージを残しませんでした。 図1の碁盤に描かれている閉曲線は、全ての空いているマス目を一度だけ通っています。Mr.X はこのような閉曲線をメッセージとして残しました。

図1

Mr.X は、図2の碁盤に描かれているような閉曲線は描きませんでした。

図2

後に Mr.X のメッセージは、古代遺跡と見事に調和した宇宙人の美として、地球人に夢とロマンを与える伝説となりました。しかし、長年に渡る風化によってメッセージは消えてしまい、伝説だけが残りました。

碁盤の情報を入力とし、Mr.X がその碁盤上にメッセージを残した場合は Yes と、残さなかった場合は No と出力するプログラムを作成してください。ただし、全てのマスに石像が配置されている場合は、No と出力することとします。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。

W H
c1,1 c1,2 ... c1,W
c2,1 c2,2 ... c2,W

:
cH,1 cH,2 ... cH,W

1 行目に碁盤の横方向に並ぶマス目の数 W, 縦方向に並ぶマス目の数 H (1 ≤ W, H ≤ 7) が与えられる。

続く H 行に碁盤の状態が与えられる。ci,j は碁盤の i 行目の左から j 番目のマス目を表す整数であり、0 のとき何も置かれていないマス目、1 のとき石像が置かれているマス目を表す。

データセットの数は 1000 を超えない。

Output

データセットごとに、Yes または No を１行に出力する。

Sample Input

5 4
0 0 0 0 0
0 1 1 0 0
0 0 1 0 1
1 0 0 0 1
5 4
0 0 0 0 0
0 1 1 0 0
0 0 0 0 1
1 0 0 0 1
0 0

Output for the Sample Input

Yes
No

Solution in C# (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static string InputPattern = "Input2";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("5 4");
            WillReturn.Add("0 0 0 0 0");
            WillReturn.Add("0 1 1 0 0");
            WillReturn.Add("0 0 1 0 1");
            WillReturn.Add("1 0 0 0 1");
            WillReturn.Add("5 4");
            WillReturn.Add("0 0 0 0 0");
            WillReturn.Add("0 1 1 0 0");
            WillReturn.Add("0 0 0 0 1");
            WillReturn.Add("1 0 0 0 1");
            WillReturn.Add("0 0");
            //Yes 
            //No 
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    //http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0236 
    static void Main()
    {
        List<string> InputList = GetInputList();
        InputList.RemoveAt(InputList.Count - 1);

        var InputIntArrList = new List<int[]>();
        foreach (string EachStr in InputList) {
            int[] WillAdd = EachStr.Split(' ').Select(X => int.Parse(X)).ToArray();
            InputIntArrList.Add(WillAdd);
        }

        //碁盤の2次元配列のListを作成 
        List<int[,]> BanArrList = CreateBanArrList(InputIntArrList);

        //foreach (int[,] EachIntArr in BanArrList) {
        //    Console.WriteLine("遺跡情報を表示");
        //    for (int Y = 0; Y <= EachIntArr.GetUpperBound(1); Y++) {
        //        for (int X = 0; X <= EachIntArr.GetUpperBound(0); X++) {
        //            Console.Write(EachIntArr[X, Y]);
        //        }
        //        Console.WriteLine();
        //    }
        //    Console.WriteLine("閉曲線を描けるか判定={0}", CanHeikyokusen(EachIntArr));
        //    Console.WriteLine(new string('■', 15));
        //}
        BanArrList.ForEach(X => Console.WriteLine(CanHeikyokusen(X) ? "Yes" : "No"));
    }

    //碁盤の2次元配列のListを作成 
    static List<int[,]> CreateBanArrList(List<int[]> pInputIntArrList)
    {
        var BanArrList = new List<int[,]>();
        var wkLineIntList = new List<int[]>();

        int RestHeight = 0;
        foreach (int[] EachIntArr in pInputIntArrList) {
            if (RestHeight == 0) {
                RestHeight = EachIntArr[1];
                continue;
            }

            wkLineIntList.Add(EachIntArr);

            if (--RestHeight == 0) {
                int[,] wkArr = new int[wkLineIntList[0].GetUpperBound(0) + 1,
                                       wkLineIntList.Count];
                for (int Y = 0; Y <= wkLineIntList.Count - 1; Y++) {
                    for (int X = 0; X <= wkLineIntList[Y].GetUpperBound(0); X++) {
                        wkArr[X, Y] = wkLineIntList[Y][X];
                    }
                }
                BanArrList.Add(wkArr);
                wkLineIntList.Clear();
            }
        }
        return BanArrList;
    }

    struct JyoutaiDef
    {
        internal int CurrX;
        internal int CurrY;
        internal HashSet<string> VisitedSet;
    }

    //閉曲線を描くことが可能な遺跡かを返す 
    static bool CanHeikyokusen(int[,] pBanArr)
    {
        //石像のないマスの数 
        int NonSekizouMasuCnt = pBanArr.Cast<int>().Count(X => X == 0);
        if (NonSekizouMasuCnt == 0) return false;

        int UB_X = pBanArr.GetUpperBound(0);
        int UB_Y = pBanArr.GetUpperBound(1);

        //石像のないマスから探索開始 
        int StaX = -1, StaY = -1;
        new Action(() =>
        {
            for (int X = 0; X <= UB_X; X++) {
                for (int Y = 0; Y <= UB_Y; Y++) {
                    if (pBanArr[X, Y] == 0) {
                        StaX = X; StaY = Y;
                        return;
                    }
                }
            }
        })();

        var stk = new Stack<JyoutaiDef>();
        JyoutaiDef WillPush;
        WillPush.CurrX = StaX;
        WillPush.CurrY = StaY;
        WillPush.VisitedSet = new HashSet<string>();
        WillPush.VisitedSet.Add(string.Format("({0},{1})", StaX, StaY));
        stk.Push(WillPush);

        while (stk.Count > 0) {
            JyoutaiDef Popped = stk.Pop();

            //クリア判定 
            if (Popped.VisitedSet.Count == NonSekizouMasuCnt) {
                //探索開始座標とのマンハッタン距離
                int Kyori = Math.Abs(Popped.CurrX - StaX)
                          + Math.Abs(Popped.CurrY - StaY);
                if (Kyori > 1) continue;

                //Console.WriteLine("解を発見");
                //foreach (string EachStr in Popped.VisitedList) {
                //    Console.Write(EachStr);
                //}
                //Console.WriteLine();
                return true;
            }

            //Push処理 
            Action<int, int> PushSyori = (pX, pY) =>
            {
                if (pX < 0 || UB_X < pX) return;
                if (pY < 0 || UB_Y < pY) return;

                //石像なら訪問不可 
                if (pBanArr[pX, pY] == 1) return;

                //再訪不可 
                string VisitStr = string.Format("({0},{1})", pX, pY);
                if (Popped.VisitedSet.Contains(VisitStr)) return;

                WillPush.CurrX = pX;
                WillPush.CurrY = pY;
                WillPush.VisitedSet = new HashSet<string>(Popped.VisitedSet);
                WillPush.VisitedSet.Add(VisitStr);
                stk.Push(WillPush);
            };
            PushSyori(Popped.CurrX, Popped.CurrY - 1);
            PushSyori(Popped.CurrX, Popped.CurrY + 1);
            PushSyori(Popped.CurrX - 1, Popped.CurrY);
            PushSyori(Popped.CurrX + 1, Popped.CurrY);
        }
        return false;
    }
}