using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("3");
WillReturn.Add("3");
WillReturn.Add("1 1 0");
WillReturn.Add("1 0 1");
WillReturn.Add("1 1 0");
WillReturn.Add("5");
WillReturn.Add("3");
WillReturn.Add("1 1 1 0 1");
WillReturn.Add("1 1 0 0 0");
WillReturn.Add("1 0 0 0 1");
WillReturn.Add("0");
WillReturn.Add("0");
//5
//5
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int CurrInd = 0;
while (true) {
int Width = int.Parse(InputList[CurrInd]);
int Height = int.Parse(InputList[CurrInd + 1]);
if (Width == 0 && Height == 0) break;
mBanArr = CreateBanArr(InputList.Skip(CurrInd + 2).Take(Height));
Solve();
CurrInd += 2 + Height;
}
}
static int[,] mBanArr;
static int UB_X;
static int UB_Y;
static HashSet<int> mCntSet = new HashSet<int>();
static HashSet<int> mVisitedSet = new HashSet<int>();
static void Solve()
{
UB_X = mBanArr.GetUpperBound(0);
UB_Y = mBanArr.GetUpperBound(1);
mCntSet.Clear();
mVisitedSet.Clear();
for (int X = 0; X <= UB_X; X++) {
for (int Y = 0; Y <= UB_Y; Y++) {
DFS(X, Y);
}
}
Console.WriteLine(mCntSet.Max());
}
static void DFS(int pCurrX, int pCurrY)
{
if (pCurrX < 0 || UB_X < pCurrX) return;
if (pCurrY < 0 || UB_Y < pCurrY) return;
if (mBanArr[pCurrX, pCurrY] == 0) return;
int CurrHash = GetHash(pCurrX, pCurrY);
if (mVisitedSet.Add(CurrHash) == false) {
return;
}
mCntSet.Add(mVisitedSet.Count);
DFS(pCurrX, pCurrY - 1);
DFS(pCurrX, pCurrY + 1);
DFS(pCurrX - 1, pCurrY);
DFS(pCurrX + 1, pCurrY);
mVisitedSet.Remove(CurrHash);
}
// 座標のハッシュ値を返す
static int GetHash(int pX, int pY)
{
return pX * 100 + pY;
}
////////////////////////////////////////////////////////////////
// IEnumerable<string>をintの2次元配列に設定する
////////////////////////////////////////////////////////////////
static int[,] CreateBanArr(IEnumerable<string> pStrEnum)
{
var StrList = pStrEnum.ToList();
if (StrList.Count == 0) {
return new int[0, 0];
}
int[] IntArr = { };
Action<string> SplitAct = pStr =>
IntArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
SplitAct(StrList[0]);
int UB_X = IntArr.GetUpperBound(0);
int UB_Y = StrList.Count - 1;
int[,] WillReturn = new int[UB_X + 1, UB_Y + 1];
for (int Y = 0; Y <= UB_Y; Y++) {
SplitAct(StrList[Y]);
for (int X = 0; X <= UB_X; X++) {
WillReturn[X, Y] = IntArr[X];
}
}
return WillReturn;
}
}