#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; }