#include<bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;

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

vector<vector<int> > make(vector<string> &grid, pii s, vector<pii> &target){
  target.push_back(s);
  vector<vector<int> > res(target.size());
  for(int i = 0;i < target.size(); i++){
    s = target[i];
    int minicost[grid.size()][grid[0].size()];
    bool visited[grid.size()][grid[0].size()];
    memset(visited, 0, sizeof(visited));
    for(int i = 0; i < grid.size(); i++){
      for(int j = 0; j < grid[0].size(); j++){
	minicost[i][j] = 1e9;
      }
    }
    queue<piii> que;
    que.push(mp(0, s));
    visited[s.second][s.first] = true;
    minicost[s.second][s.first] = 0;
    //cout << "x:" << s.first << " y:" << s.second << endl;
    while(que.size()){
      //cout << "i:" << i << endl;
      int c = que.front().first;
      int x = que.front().second.first;
      int y = que.front().second.second;
      que.pop();
      for(int i = 0; i < 4; i++) {
	int nx = x + dx[i], ny = y + dy[i];
	if(0 <= nx && nx < w && 
	   0 <= ny && ny < h && 
	   !visited[ny][nx] &&
	   grid[ny][nx] != 'x' &&
	   minicost[ny][nx] > c + 1){
	  minicost[ny][nx] = c + 1;
	  que.push(mp(c + 1, mp(nx, ny)));
	  visited[ny][nx] = true;
	}
      }
    }
    // cout << "minicost:" << endl;
    // for(int i = 0; i < h; i++){
    //   for(int j = 0; j < w; j++){
    // 	cout << minicost[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    for(int j = 0; j < target.size(); j++){
      res[i].push_back(minicost[target[j].second][target[j].first]);
    }
  }
  return res;
}


int main(){
  while(cin >> w >> h, h){
    int n = 1;
    vector<pii> target;//x, y
    pii start;
    vector<string> grid(h);
    for(int i = 0; i < h; i++){
      cin >> grid[i];
      for(int j = 0; j < grid[i].length(); j++){
	if(grid[i][j] == '*')target.push_back(mp(j, i)), n++;
	if(grid[i][j] == 'o')start = mp(j, i);
      }
    }
    int dp[1<<n][n];
    for(int i = 0; i < (1<<n); i++){
      for(int j = 0; j < n; j++){
	dp[i][j] = 1e9;
      }
    }
    
    //cout << w << " " << h << endl;
    vector<vector<int> > g = make(grid, start, target);
    // for(int i = 0; i < g.size(); i++){
    //   cout << "i:" << i << endl;
    //   for(int j = 0; j < g[i].size(); j++){
    // 	cout << g[i][j] << " ";
    //   }
    //   cout << endl;
    // }
    priority_queue<piii, vector<piii>, greater<piii> > que;
    que.push(mp(0, mp((1<<(n - 1)), n - 1)));
    bool flag = true;
    while(que.size()){
      int cost  = que.top().first;
      int state = que.top().second.first;
      int v     = que.top().second.second;
      que.pop();
      // cout << "cost :" << cost  << endl;
      // cout << "v    :" << v     << endl;
      // cout << "state:" << state << endl;
      if(state == (1<<n) - 1){
	cout << cost << endl;
	flag = false;
	  break;
      }
      for(int i = 0; i < g[v].size(); i++){
	if(i == v)continue;
	int nv = i;
	
	if(dp[(state | (1<<i))][i] > cost + g[v][i]){
	  dp[(state | (1<<i))][i] = cost + g[v][i];
	  que.push(mp(cost + g[v][i], mp((state | (1<<i)), i)));
	}
      }
    }
    if(flag)cout << -1 << endl;
  }
  return 0;
}

Measured memory_bytes: 1356