暴力枚舉
#include<iostream>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF (1<<30)
struct Point
{
int x,y;
void get(int xx,int yy)
{
x=xx;
y=yy;
}
}p[20];
struct Num
{
int oneNum,pos;
}num[1<<20];
int cnt;
int ans;
int n,m;
char map[220][220];
int bri[220][220];
int dir1[4][2]={-1,0, 1,0, 1, 0, -1,0};
int dir2[4][2]={ 0,1, 0,1, 0,-1, 0,-1};
bool cmp(Num a,Num b)
{
return a.oneNum<=b.oneNum;
}
int getNum(int x)
{
int num=0;
while(x)
{
num++;
x&=x-1;
}
return num;
}
int judge(int i,int d)
{
int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]=='#')
return 0;
if(ttx>=0&&ttx<n&&tty>=0&&tty<m&&map[ttx][tty]=='#')
return 0;
return 1;
}
void add(int i,int d,int& num)
{
int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
if(bri[p[i].x][p[i].y]==0)
num++;
bri[p[i].x][p[i].y]++;
if(tx>=0&&tx<n&&ty>=0&&ty<m)
{
if(bri[tx][ty]==0)
num++;
bri[tx][ty]++;
}
if(ttx>=0&&ttx<n&&tty>=0&&tty<m)
{
if(bri[ttx][tty]==0)
num++;
bri[ttx][tty]++;
}
}
void sub(int i,int d,int& num)
{
int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
bri[p[i].x][p[i].y]--;
if(bri[p[i].x][p[i].y]==0)
num--;
if(tx>=0&&tx<n&&ty>=0&&ty<m)
{
bri[tx][ty]--;
if(bri[tx][ty]==0)
num--;
}
if(ttx>=0&&ttx<n&&tty>=0&&tty<m)
{
bri[ttx][tty]--;
if(bri[ttx][tty]==0)
num--;
}
}
int solve(int S,int k)
{
int num=0;
for(int i=0;i<cnt;i++)
{
if(i==k)
continue;
if(S&(1<<i))
{
if(judge(i,0))
add(i,0,num);
else
return 0;
}
}
for(int i=0;i<4;i++)
if(judge(k,i))
{
add(k,i,num);
if(num==cnt)
return 1;
sub(k,i,num);
}
return 0;
}
int main()
{
while(cin>>n>>m&&n+m)
{
cnt=0;
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
for(int j=0;j<m;j++)
if(map[i][j]=='.')
p[cnt++].get(i,j);
}
if(cnt==0)
{
cout<<0<<endl;
continue;
}
for(int i=0;i<(1<<cnt);i++)
{
num[i].pos=i;
num[i].oneNum=getNum(i);
}
sort(num,num+(1<<cnt),cmp);
ans=INF;
int flag=0;
for(int r=0;r<(1<<cnt)&&flag==0;r++)
{
int i=num[r].pos;
for(int j=0;j<cnt;j++)
{
if(i&(1<<j))
{
for(int f=0;f<cnt;f++)
bri[p[f].x][p[f].y]=0;
if(solve(i,j))
{
ans=min(ans,num[r].oneNum);
flag=1;
break;
}
}
}
}
if(ans>=INF)
cout<<-1<<endl;
else
cout<<ans<<endl;
}
return 0;
}