#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int n,m,k,ka,ks;
char g[100][100];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
vector<int> islands[10000];
int hash_func(int x,int y){//返回坐标元素值
return x*m+y;
}
int inb(int x,int y){//判断是否越界
return x>0&&x<n&&y>=0&&y<m;
}
void dfs(int x,int y,vector<int>&island){
vis[x][y]=true;
island.push_back(has_fun(x,y));
for(int d=0;d<4;d++){
int _x=x+dx[d];
int _y=y+dy[d];
if(inb(_x,_y)&&!vis[_x][_y]&&g[_x][_y]=='#')dfs(_x,_y,island);
}
}
bool shape_similar(vector<int>&islandi,vector<int>&islandj){//判断俩个区域图像是否一样
if(islandi.size()!=islandj.size())return false;//长度判断
int d=islandi[0]-islandj[0];
for(int i=1;i<island.size();i++)//判断是否满足vector中对应编号的差是一个定值
if(island[i]-island[j]!=d)return false;
return true;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)scanf("%d",g[i]);
memset(vis,false,sizeof(vis));
k=0;//连通分量计数
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(!vis[i][j]&&g[i][j]=='#'){
island[k].clear();
dfs(i,j,islands[k]);
sort(island[k].begin(),island[k].end());
k++;
}
}
ka=ks=0;
for(int i=0;i<k;i++){
bool fa=false,fs=false;
for(int j=0;j<i;j++){
if(island[i].size()==island[j].size())
fa=true;
if(shape_similar(island[i],island[j]))
fs=true;
}
if(!fa)ka++;//面积不同海岛数目
if(!fs)ks++;//形状不同海岛数目
}
printf("%d%d%d",k,ka,ks);
return 0;
}