#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
const int N = 16;
int L[N*N*N], R[N*N*N], U[N*N*N], D[N*N*N], Sum[N*N*N], Row[N*N*N], Col[N*N*N];
char inimap[N][N];
int map[N][N];
int n, m, cntrow, cntcol;
int lenx, id, deep, anslen;
bool OK;
int move[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
bool flag[50];
void init() {
for(int i = 0; i < n; i ++) {
scanf("%s", inimap[i]);
}
memset(map, 0, sizeof(map));
cntrow = 0;
cntcol = 0;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
if ( inimap[i][j] == '*') map[i][j] = -1;
if ( inimap[i][j] == '.') map[i][j] = 300 + (++cntrow);
if ( inimap[i][j] == '#') map[i][j] = (++cntcol);
}
}
// for(int i = 0; i < n; i ++) {
// for(int j = 0; j < m; j ++) {
// printf("%5d", map[i][j]);
// }puts("");
// }
}
void pre() {
for(int i = 0; i <= cntcol; i ++) {
L[i] = i - 1;
R[i] = i + 1;
U[i] = D[i] = i;
Sum[i] = 0;
}
L[0] = cntcol; R[cntcol] = 0;
id = cntcol + 1;
}
inline void insert(int i, int *xx) {
for(int j = 0; j < lenx; j ++, id ++) {
int x = xx[j];
Row[id] = i;
Col[id] = x;
Sum[x] ++;
U[id] = x;
D[id] = D[x];
U[D[x]] = id;
D[x] = id;
if( j == 0 ) {
L[id] = R[id] = id;
} else {
L[id] = id - 1;
R[id] = id - j;
R[id-1] = id;
L[id-j] = id;
}
}
}
inline int expend(int i, int j, int k) {
int t = 1;
while(true) {
int x = i + move[k][0] * t;
int y = j + move[k][1] * t;
if( x < 0 || x >= n || y < 0 || y >= m || map[x][y] == -1) return -1;
if( map[x][y] > 0 && map[x][y] < 300 ) return map[x][y];
t ++;
}
}
struct node {
int len;
int x[5];
bool operator < (const node a) const {
len > a.len;
}
};
void build() {
int x[5], r = 0;
node tp[15*15] ;
int cnt = 0;
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
lenx = 0;
if( map[i][j] > 300 ) {
for(int k = 0; k < 4; k ++) {
int t = expend(i, j, k);
if( t == -1 ) continue;
x[lenx++] = t;
}
tp[cnt].len = lenx;
for(int k = 0; k < lenx; k ++) tp[cnt].x[k] = x[k];
cnt ++;
}
}
}
memset(flag, 0, sizeof( flag));
std::sort(tp, tp + cnt);
for(int i = 0; i < cnt; i ++) {
int j;
for(j = 0; j < tp[i].len; j ++) {
if( flag[tp[i].x[j]] ) break;
flag[tp[i].x[j]] = 1;
}
if( j == tp[i].len) {
lenx = tp[i].len;
insert(++r, tp[i].x);
}
}
}
void remove(int &c) {
for(int i = D[c]; i != c ; i = D[i]) {
L[R[i]] = L[i];
R[L[i]] = R[i];
}
}
void resume(int &c) {
for(int i = U[c]; i != c ; i = U[i]) {
L[R[i]] = i;
R[L[i]] = i;
}
}
inline int Astar() {
int res = 0;
bool vis[16] = {false};
for(int i = R[0]; i != 0; i =R[i]) {
if( !vis[ i ] ) {
vis[ i ] = true;
res ++;
for(int j = D[i]; j != i; j = D[j]) {
for(int k = R[j]; k != j; k = R[k]) {
vis[ Col[k] ] = true;
}
}
}
}
return res;
}
void dfs(int dep) {
//printf("%d %d %d\n", Astar(), dep, deep) ;
//system("pause");
if( Astar() + dep > deep ) return ;
if(R[0] == 0) {
anslen = dep;
OK = true;
return;
}
int idx = R[0];
// printf("%d\n", idx);
for(int i = R[0] ; i != 0 ; i = R[i]) {
if(Sum[i] < Sum[idx]) {
idx = i;
//if( Sum[idx] <= 1 ) break;
}
}
for(int i = D[idx] ; i != idx; i = D[i]) {
remove(i);
for(int j = R[i] ; j != i ; j = R[j]) remove(j);
dfs( dep + 1 );
for(int j = L[i] ; j != i ; j = L[j]) resume(j);
resume(i);
if( OK ) return;
}
}
int main() {
while( scanf("%d %d", &n, &m) != EOF ) {
init();
pre();
build();
deep = 1;
OK = false;
anslen = 257;
while( !OK ) {
dfs(0);
deep ++;
}
printf("%d\n", anslen);
}
//while(1);
return 0;
}