#include<iostream>
using namespace std;
typedef struct node{
int east,south,west,north;
bool used;
}Lnode;
int n,m;
int num,area;
Lnode castle[55][55];
void init()
{
int tsum;
Lnode nd;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
cin>>tsum;
nd.west=(tsum&(1<<0))>>0;
nd.north=(tsum&(1<<1))>>1;
nd.east=(tsum&(1<<2))>>2;
nd.south=(tsum&(1<<3))>>3;
nd.used=false;
castle[i][j]=nd;
}
}
void dfs(int x,int y,int& depth)
{
if(x<0||x>n||y<0||y>m)
return ;
if(!castle[x][y].used){
depth++;
castle[x][y].used=true;
if(castle[x][y].west==0){
dfs(x,y-1,depth);
}
if(castle[x][y].north==0){
dfs(x-1,y,depth);
}
if(castle[x][y].east==0){
dfs(x,y+1,depth);
}
if(castle[x][y].south==0){
dfs(x+1,y,depth);
}
}
}
int main()
{
cin>>n>>m;
init();
num=0;
int max=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(!castle[i][j].used){
num++;
area=0;
dfs(i,j,area);
if(max<area)
max=area;
}
}
cout<<num<<endl;
cout<<max<<endl;
return 0;
}
//并查集,哈哈
#include <iostream>
#include <cstring>
using namespace std;
int parent[3000];
int find(int x) //寻找根节点 和 路径压缩
{
if(parent[x]<0)
return x;
parent[x]=find(parent[x]);
return parent[x]; }
void uni(int x,int y) //集合合并
{
int root1,root2,t;
root1=find(x);
root2=find(y);
if(root1==root2)
return;
t=parent[root1]+parent[root2];
if(parent[root1]<parent[root2])
{
parent[root2]=root1;
parent[root1]=t;
}
else
{
parent[root1]=root2;
parent[root2]=t;
}
}
int main ()
{
int n,m,sum,a[3000];
while (cin>>n>>m)
{
memset(parent,-1,sizeof(parent));
sum = n * m;
for (int i = 1; i <= sum; i++)
{
cin>>a[i];
if (!(a[i] & 1))
{
if (i%m - 1 > 0) uni(i,i-1);
}
a[i] /= 2;
if (!(a[i] & 1))
{
if (i > m) uni(i,i-m);
}
a[i] /= 2;
if (!(a[i] & 1))
{
if (i%m != 0) uni(i,i+1);
}
a[i] /= 2;
if (!(a[i] & 1))
{
if (i+m <= sum)
uni(i,i+m);
}
}
int max = -1,ans = 0;
for (int i = 1; i <= sum; i++)
{
if (parent[i]*-1 > max)
max = parent[i]*-1;
if (parent[i] < 0) ans ++;
}
cout<<ans<<endl;
cout<<max<<endl;
}
return 0;
}
#include<stdio.h>
#define DEN 51
struct DIR
{
int east,south,west,north;
}mark[DEN][DEN]; //定义一个结构体,用来存储东南西北是否能通过
int tmp[DEN][DEN]; //用来做标记的,看是否已经走过
int date[DEN][DEN]; //用来来存储输入的数据部分
int m,n,max; //max用来存储最大值
int t; //t用来计数
void sign() //调用sign函数,用来计算东西南北四个方向能否通过
{
int i,j;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
if(!(date[i][j]&1))
mark[i][j].west=1;//西能通过
if(!(date[i][j]&2))
mark[i][j].north=1;//北能通过
if(!(date[i][j]&4))
mark[i][j].east=1;//东能通过
if(!(date[i][j]&8))
mark[i][j].south=1;//南能通过
}
}
void find(int i,int j) //用find来查找连通房间
{
if(t>max)
max=t;
if(mark[i][j].east==1&&tmp[i][j+1]==0) //如果东边不是墙,并且东边的一个房间没有标记,就进入。
{
tmp[i][j+1]=1; //进入之后马上标记为已走过哦
t++; //总房间个数加一
find(i,j+1); //然后进入
}
if(mark[i][j].south==1&&tmp[i+1][j]==0) //同理
{
tmp[i+1][j]=1;
t++;
find(i+1,j);
}
if(mark[i][j].west==1&&tmp[i][j-1]==0) //同理
{
tmp[i][j-1]=1;
t++;
find(i,j-1);
}
if(mark[i][j].north==1&&tmp[i-1][j]==0) //同理
{
tmp[i-1][j]=1;
t++;
find(i-1,j);
}
return ;
}
int main()
{
int i,j,k=0;
scanf("%d%d",&m,&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&date[i][j]);
sign();
for(i=0;i<m;i++)
for(j=0;j<n;j++)
{
if(!tmp[i][j]) //未被标记才能进入
{
t=1; //一进入t就应该为1了哦
tmp[i][j]=1;
find(i,j);
k++; //每能调用一次,就证明一定有一个房间哦,所以要加一
}
}
printf("%d\n%d\n",k,max);//输出结果
return 0;
}