#include<iostream>
using namespace std;
#include<time.h>
int m,n;
char map[25][25];
int vis[25][25];
typedef struct node
{
int x;
int y;
}node;
node queue[500];//放需要清理的点
int total;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
typedef struct snode
{
int x;
int y;
int step;
}snode;
snode sq[50000];
int flag,tempdis;
int dis[50][50];//放脏的地之间的最小步数
int minstep;
int visit[50];//脏的点的标志位
void bfs(int sx,int sy,int ex,int ey)
{
int head,tail;
head=tail=0;
vis[sx][sy]=1;
snode start;
start.x=sx;
start.y=sy;
start.step=0;
sq[tail++]=start;
while(head!=tail)
{
snode cur,next;
cur=sq[head++];
if(cur.x==ex&&cur.y==ey)
{
tempdis=cur.step;
break;
}
for(int i=0;i<4;i++)
{
next.x=cur.x+dx[i];
next.y=cur.y+dy[i];
if(next.x>=0&&next.x<m&&next.y>=0&&next.y<n&&vis[next.x][next.y]==0&&map[next.x][next.y]!='x')
{
vis[next.x][next.y]=1;
next.step=cur.step+1;
sq[tail++]=next;
}
}
}
}
void dfs(int x,int sum,int step)
{
if(sum>minstep)
return;
if(step==total)
{
if(sum<minstep)
minstep=sum;
return;
}
for(int i=1;i<=total;i++)//从1开始,因为0的点是开始节点
{
if(visit[i]==0)
{
visit[i]=1;
dfs(i,sum+dis[x][i],step+1);
visit[i]=0;
}
}
}
int main()
{
//long t1,t2;
//t1=clock();
//freopen("input.txt","r",stdin);
while(1)
{
cin>>n>>m;
if(n==0&&m==0)
break;
total=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>map[i][j];
if(map[i][j]=='*')
{
total++;
queue[total].x=i;
queue[total].y=j;
}
if(map[i][j]=='o')
{
queue[0].x=i;
queue[0].y=j;
}
}
}
for(int i=0;i<=total;i++)
{
for(int j=0;j<=total;j++)
{
dis[i][j]=99999999;
}
}
for(int i=0;i<=total;i++)
{
for(int j=i;j<=total;j++)
{
if(i!=j)
{
for(int i=0;i<25;i++)
for(int j=0;j<25;j++)
vis[i][j]=0;
tempdis=99999999;
bfs(queue[i].x,queue[i].y,queue[j].x,queue[j].y);
dis[i][j]=tempdis;
dis[j][i]=tempdis;
}
if(i==j)
dis[i][j]=0;
}
}
flag=1;
for(int i=0;i<=total;i++)
{
for(int j=0;j<=total;j++)
{
if(dis[i][j]==99999999)
{
flag=0;
break;
}
}
}
if(flag==0)
{
cout<<-1<<endl;
continue;
}
minstep=99999999;
dfs(0,0,0);
cout<<minstep<<endl;
}
//t2=clock();
//cout<<t2-t1<<endl;
return 0;
}