{$MODE OBJFPC}
PROGRAM MCLEAN;
uses math;
const
wmax = 21;
hmax = 21;
oo = trunc(1e18);
kx : array[1..4] of integer = (-1,0,1,0);
ky : array[1..4] of integer = (0,1,0,-1);
type
point = record
x,y : integer;
end;
var
w,h,n : integer;
p : array[1..11] of point;
a : array[1..wmax,1..hmax] of char;
f : array[1..11,0..1 shl 11] of int64;
d : array[1..11,1..11] of int64;
res : int64;
procedure bfs (s : integer);
var
q : array[1..21] of point;
l,r : integer;
free : array[1..wmax,1..hmax] of boolean;
c : array[1..wmax,1..hmax] of int64;
u,v,ux,vy : integer;
k,i : integer;
begin
fillchar(q,sizeof(q),0);
fillchar(free,sizeof(free),true);
l:= 1;
r:= 1;
q[1].x:= p[s].x;
q[1].y:= p[s].y;
free[p[s].x,p[s].y]:= false;
fillchar(c,sizeof(c),0);
while l <= r do
begin
u:= q[l].x;
v:= q[l].y;
inc(l);
for k:=1 to 4 do
begin
ux:= u + kx[k];
vy:= v + ky[k];
if (ux > 0) and (ux <= h) and (vy > 0) and (vy <= w) and (a[ux][vy] <> 'x') then
if (free[ux,vy]) then
begin
c[ux,vy]:= c[u,v] + 1;
free[ux,vy]:= false;
inc(r);
q[r].x:= ux;
q[r].y:= vy;
end;
end;
end;
for i:=1 to n do
begin
d[s,i]:= c[p[i].x,p[i].y];
if (i <> s) and (d[s,i] = 0) then d[s,i]:= oo;
end;
end;
function getbit (x,i : integer) : integer;
begin
getbit:= (x shr i) and 1;
end;
function turnoff (x,i : integer) : integer;
begin
turnoff:= x and not (1 shl i);
end;
procedure main;
var
i,j : integer;
first,last,st,pres : integer;
count : integer;
b : array[1..11] of integer;
begin
fillchar(p,sizeof(p),0);
n:= 1;
for i:=1 to h do
begin
readln(a[i]);
for j:=1 to w do
begin
if a[i][j] = 'o' then
begin
p[1].x:= i;
p[1].y:= j;
end
else
if a[i][j] = '*' then
begin
inc(n);
p[n].x:= i;
p[n].y:= j;
end;
end;
end;
for i:=1 to n do
bfs(i);
first:= 1;
last:= 1 shl n - 1;
for i:=1 to n do
for st:= 0 to last do
f[i,st]:= oo;
for i:=1 to n do
f[i,1 shl (i-1)]:= d[1,i];
for st:= first to last do
begin
count:= 0;
for i:=1 to n do
if getbit(st,i-1) = 1 then
begin
inc(count);
b[count]:= i;
end;
for i:=1 to count do
begin
pres:= turnoff(st,b[i] - 1);
for j:=1 to count do
if (i <> j) then
f[b[i],st]:= min(f[b[i],st],f[b[j],pres] + d[b[i],b[j]]);
end;
end;
res:= oo;
for i:=1 to n do
res:= min(res,f[i,last]);
writeln(res);
end;
BEGIN
//assign(input,'input.inp');reset(input);
//assign(output,'output.out');rewrite(output);
repeat
readln(w,h);
if w*h = 0 then break;
main;
until false;
END.
eyRNT0RFIE9CSkZQQ30KUFJPR1JBTSBNQ0xFQU47CnVzZXMgbWF0aDsKY29uc3QKICAgIHdtYXggPSAyMTsKICAgIGhtYXggPSAyMTsKICAgIG9vID0gdHJ1bmMoMWUxOCk7CiAgICBreCA6IGFycmF5WzEuLjRdIG9mIGludGVnZXIgPSAoLTEsMCwxLDApOwogICAga3kgOiBhcnJheVsxLi40XSBvZiBpbnRlZ2VyID0gKDAsMSwwLC0xKTsKdHlwZQogICAgcG9pbnQgPSByZWNvcmQKICAgICAgICB4LHkgOiBpbnRlZ2VyOwogICAgZW5kOwp2YXIKICAgIHcsaCxuIDogaW50ZWdlcjsKICAgIHAgOiBhcnJheVsxLi4xMV0gb2YgcG9pbnQ7CiAgICBhIDogYXJyYXlbMS4ud21heCwxLi5obWF4XSBvZiBjaGFyOwogICAgZiA6IGFycmF5WzEuLjExLDAuLjEgc2hsIDExXSBvZiBpbnQ2NDsKICAgIGQgOiBhcnJheVsxLi4xMSwxLi4xMV0gb2YgaW50NjQ7CiAgICByZXMgOiBpbnQ2NDsKcHJvY2VkdXJlIGJmcyAocyA6IGludGVnZXIpOwp2YXIKICAgIHEgOiBhcnJheVsxLi4yMV0gb2YgcG9pbnQ7CiAgICBsLHIgOiBpbnRlZ2VyOwogICAgZnJlZSA6IGFycmF5WzEuLndtYXgsMS4uaG1heF0gb2YgYm9vbGVhbjsKICAgIGMgOiBhcnJheVsxLi53bWF4LDEuLmhtYXhdIG9mIGludDY0OwogICAgdSx2LHV4LHZ5IDogaW50ZWdlcjsKICAgIGssaSA6IGludGVnZXI7CmJlZ2luCiAgICBmaWxsY2hhcihxLHNpemVvZihxKSwwKTsKICAgIGZpbGxjaGFyKGZyZWUsc2l6ZW9mKGZyZWUpLHRydWUpOwogICAgbDo9IDE7CiAgICByOj0gMTsKICAgIHFbMV0ueDo9IHBbc10ueDsKICAgIHFbMV0ueTo9IHBbc10ueTsKICAgIGZyZWVbcFtzXS54LHBbc10ueV06PSBmYWxzZTsKICAgIGZpbGxjaGFyKGMsc2l6ZW9mKGMpLDApOwogICAgd2hpbGUgbCA8PSByIGRvCiAgICAgICAgYmVnaW4KICAgICAgICAgICAgdTo9IHFbbF0ueDsKICAgICAgICAgICAgdjo9IHFbbF0ueTsKICAgICAgICAgICAgaW5jKGwpOwogICAgICAgICAgICBmb3Igazo9MSB0byA0IGRvCiAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgIHV4Oj0gdSArIGt4W2tdOwogICAgICAgICAgICAgICAgICAgIHZ5Oj0gdiArIGt5W2tdOwogICAgICAgICAgICAgICAgICAgIGlmICh1eCA+IDApIGFuZCAodXggPD0gaCkgYW5kICh2eSA+IDApIGFuZCAodnkgPD0gdykgYW5kIChhW3V4XVt2eV0gPD4gJ3gnKSB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcmVlW3V4LHZ5XSkgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjW3V4LHZ5XTo9IGNbdSx2XSArIDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlZVt1eCx2eV06PSBmYWxzZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmMocik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcVtyXS54Oj0gdXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcVtyXS55Oj0gdnk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQ7CiAgICAgICAgICAgICAgICBlbmQ7CiAgICAgICAgZW5kOwogICAgZm9yIGk6PTEgdG8gbiBkbwogICAgICAgIGJlZ2luCiAgICAgICAgICAgIGRbcyxpXTo9IGNbcFtpXS54LHBbaV0ueV07CiAgICAgICAgICAgIGlmIChpIDw+IHMpIGFuZCAoZFtzLGldID0gMCkgdGhlbiBkW3MsaV06PSBvbzsKICAgICAgICBlbmQ7CmVuZDsKZnVuY3Rpb24gZ2V0Yml0ICh4LGkgOiBpbnRlZ2VyKSA6IGludGVnZXI7CmJlZ2luCiAgICBnZXRiaXQ6PSAoeCBzaHIgaSkgYW5kIDE7CmVuZDsKZnVuY3Rpb24gdHVybm9mZiAoeCxpIDogaW50ZWdlcikgOiBpbnRlZ2VyOwpiZWdpbgogICAgdHVybm9mZjo9IHggYW5kIG5vdCAoMSBzaGwgaSk7CmVuZDsKcHJvY2VkdXJlIG1haW47CnZhcgogICAgaSxqIDogaW50ZWdlcjsKICAgIGZpcnN0LGxhc3Qsc3QscHJlcyA6IGludGVnZXI7CiAgICBjb3VudCA6IGludGVnZXI7CiAgICBiIDogYXJyYXlbMS4uMTFdIG9mIGludGVnZXI7CmJlZ2luCiAgICBmaWxsY2hhcihwLHNpemVvZihwKSwwKTsKICAgIG46PSAxOwogICAgZm9yIGk6PTEgdG8gaCBkbwogICAgICAgIGJlZ2luCiAgICAgICAgICAgIHJlYWRsbihhW2ldKTsKICAgICAgICAgICAgZm9yIGo6PTEgdG8gdyBkbwogICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICBpZiBhW2ldW2pdID0gJ28nIHRoZW4KICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBbMV0ueDo9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwWzFdLnk6PSBqOwogICAgICAgICAgICAgICAgICAgICAgICBlbmQKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgaWYgYVtpXVtqXSA9ICcqJyB0aGVuCiAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmMobik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwW25dLng6PSBpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFtuXS55Oj0gajsKICAgICAgICAgICAgICAgICAgICAgICAgZW5kOwogICAgICAgICAgICAgICAgZW5kOwogICAgICAgIGVuZDsKICAgIGZvciBpOj0xIHRvIG4gZG8KICAgICAgICBiZnMoaSk7CiAgICBmaXJzdDo9IDE7CiAgICBsYXN0Oj0gMSBzaGwgbiAtIDE7CiAgICBmb3IgaTo9MSB0byBuIGRvCiAgICAgICAgZm9yIHN0Oj0gMCB0byBsYXN0IGRvCiAgICAgICAgICAgIGZbaSxzdF06PSBvbzsKICAgIGZvciBpOj0xIHRvIG4gZG8KICAgICAgICBmW2ksMSBzaGwgKGktMSldOj0gZFsxLGldOwogICAgZm9yIHN0Oj0gZmlyc3QgdG8gbGFzdCBkbwogICAgICAgIGJlZ2luCiAgICAgICAgICAgIGNvdW50Oj0gMDsKICAgICAgICAgICAgZm9yIGk6PTEgdG8gbiBkbwogICAgICAgICAgICAgICAgaWYgZ2V0Yml0KHN0LGktMSkgPSAxIHRoZW4KICAgICAgICAgICAgICAgICAgICBiZWdpbgogICAgICAgICAgICAgICAgICAgICAgICBpbmMoY291bnQpOwogICAgICAgICAgICAgICAgICAgICAgICBiW2NvdW50XTo9IGk7CiAgICAgICAgICAgICAgICAgICAgZW5kOwogICAgICAgICAgICBmb3IgaTo9MSB0byBjb3VudCBkbwogICAgICAgICAgICAgICAgYmVnaW4KICAgICAgICAgICAgICAgICAgICBwcmVzOj0gdHVybm9mZihzdCxiW2ldIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgZm9yIGo6PTEgdG8gY291bnQgZG8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPD4gaikgdGhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgZltiW2ldLHN0XTo9IG1pbihmW2JbaV0sc3RdLGZbYltqXSxwcmVzXSArIGRbYltpXSxiW2pdXSk7CiAgICAgICAgICAgICAgICBlbmQ7CiAgICAgICAgZW5kOwogICAgcmVzOj0gb287CiAgICBmb3IgaTo9MSB0byBuIGRvCiAgICAgICAgcmVzOj0gbWluKHJlcyxmW2ksbGFzdF0pOwogICAgd3JpdGVsbihyZXMpOwplbmQ7CkJFR0lOCiAgICAvL2Fzc2lnbihpbnB1dCwnaW5wdXQuaW5wJyk7cmVzZXQoaW5wdXQpOwogICAgLy9hc3NpZ24ob3V0cHV0LCdvdXRwdXQub3V0Jyk7cmV3cml0ZShvdXRwdXQpOwogICAgcmVwZWF0CiAgICAgICAgcmVhZGxuKHcsaCk7CiAgICAgICAgaWYgdypoID0gMCB0aGVuIGJyZWFrOwogICAgICAgIG1haW47CiAgICB1bnRpbCBmYWxzZTsKRU5ELgoK