// Original C++ solution (slower):
#include<iostream>

#include<iomanip>

#include<vector>

#include<map>

#include<algorithm>

#include<string>

#include<cstring>

#include<queue>

#include<cctype>

using namespace std;

#define fr first

#define sc second

typedef pair<int,int> Pt;

typedef pair<Pt ,int> P;

Pt ST,GL;

int h,w,c,used[20][20][1 << 10],d[]={0,1,0,-1};

char mas[20][20];

int bfs();

int main(){

  while(cin >> w >> h && w){

    c = 0;

    for(int i=0;i<h;i++){

      for(int j=0;j<w;j++){

        cin >> mas[i][j];

        if(mas[i][j] == 'o') ST = Pt(i,j);

        else if(mas[i][j] == '*') mas[i][j] = c++;

      }

    }

    cout << bfs() << endl;

  }

}

int bfs(){

  memset(used,-1,sizeof(used));

  queue<P> que;

  que.push(P(ST,0));

  used[ST.fr][ST.sc][0] = 0;

  while(!que.empty()){

    P p = que.front();

    que.pop();

    if(p.sc==(1<<c)-1) return used[p.fr.fr][p.fr.sc][p.sc];

    int log = used[p.fr.fr][p.fr.sc][p.sc];

    for(int i=0;i<4;i++){

      int nx = d[i] + p.fr.fr,ny = d[3-i] + p.fr.sc;

      int bits = p.sc;

      if(nx>=0&&nx<h&&ny>=0&&ny<w){

        if(mas[nx][ny] == 'x') continue;

        if(mas[nx][ny] >= 0 && mas[nx][ny] < 10){

          bits |= 1<<mas[nx][ny] ;

        }

        if(used[nx][ny][bits] != -1) continue;

        que.push(P(Pt(nx,ny),bits));

        used[nx][ny][bits] = log + 1;

      }

    }

  }

  return -1;

}

// Optimized solution to the same problem (faster):
#include<iostream>

#include<algorithm>

#include<queue>

#include<cstring>

using namespace std;

#define INF 1 << 29

typedef pair< int , int > Pi;

int h, w;

char mas[50][50];

int graph[11][11];

int min_cost[50][50];

Pi gomi[11];

int gomi_size, uoo;

int memo[12][1 << 11];

const int dy[] = { 1, 0, 0, -1}, dx[] = { 0, 1, -1, 0};



int rec(int idx, int used)

{

  if(used == (1 << gomi_size) - 1) return 0;

  if(memo[idx][used]) return memo[idx][used];



  int ret = INF;

  for(int i = 0; i < gomi_size; i++){

    if(!(used & (1 << i)) && graph[idx][i] != -1){

      ret = min(ret, rec(i, used | (1 << i)) + graph[idx][i]);

    }

  }



  return memo[idx][used] = ret;

}





int bfs(Pi a, Pi b)

{

  memset( min_cost, -1, sizeof(min_cost));

  queue< Pi > que;

  que.push(a);

  min_cost[a.first][a.second] = 0;

  while(!que.empty()){

    Pi p = que.front(); que.pop();

    if(p == b) return min_cost[p.first][p.second];

    for(int i = 0; i < 4; i++){

      int ny = p.first + dy[i], nx = p.second + dx[i];

      if(ny < 0 || ny >= h || nx < 0 || nx >= w) continue;

      if(mas[ny][nx] != 'x' && min_cost[ny][nx] == -1){

        min_cost[ny][nx] = min_cost[p.first][p.second] + 1;

        que.push( Pi( ny, nx));

      }

    }

  }

  return -1;

}



int main()

{

  while(cin >> w >> h, w){

gomi_size = 0;

  for(int i = 0; i < h; i++){

    for(int j = 0; j < w; j++){

      cin >> mas[i][j];

      if(mas[i][j] == '*' || mas[i][j] == 'o'){

        gomi[gomi_size++] = Pi( i, j);

        if(mas[i][j] == 'o') uoo = gomi_size - 1;

      }

    }

  }

  for(int i = 0; i < gomi_size; i++){

    for(int j = i + 1; j < gomi_size; j++){

      graph[i][j] = graph[j][i] = bfs(gomi[i], gomi[j]);

    }

  }



  //巡回セールスマン！！

  //さのぴーさんよろしく

memset( memo, 0, sizeof(memo));

  int ret = rec( uoo, 1 << uoo);



  if(ret != INF) cout << ret << endl;

  else cout << -1 << endl;

}

  return(0);

}

// Fastest known solution for this problem: