#include <iostream>
#include <cstdio>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
#include <cctype>
#include <complex>
#include <string>
#include <sstream>

using namespace std;

#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(),c.rend()
#define mp(a,b) make_pair((a),(b))
#define eq ==

typedef long long ll;
typedef complex<double> point;
typedef pair<int,int> pii;

// →↑←↓
const int dx[] = {1,0,-1,0};
const int dy[] = {0,-1,0,1};


const double EPS = 1e-9;

struct State{
    int y,x,dist;
    State(int y,int x,int dist) : y(y),x(x),dist(dist) {};
};
const int INF = 1<<30;

int main(){
    while(true){
        int w,h;
        cin >> w >> h;
        if(w == 0 and h == 0) break;
        vector<string> field(h);
        vector<pii> duty;
        map<pii,int> dutymap;
        pii me;

        for(int i=0;i<h;i++){
            cin >> field[i];
            for(int j=0;j<w;j++){
                if(field[i][j] == '*'){
                    duty.push_back(pii(i,j));
                    dutymap[pii(i,j)] = duty.size()-1;
                }else if(field[i][j] == 'o'){
                    me.first=i,me.second=j;
                }
            }
        }
        vector<int> medist(duty.size(),INF);
        {
            queue<State> q;
            q.push(State(me.first,me.second,0));
            vector<vector<char> > used(h,vector<char>(w,false));

            while(not q.empty()){
                int y = q.front().y;
                int x = q.front().x;
                int dist = q.front().dist;
                q.pop();
                if(used[y][x]) continue;
                used[y][x] = true;
                if(dutymap.find(pii(y,x)) != dutymap.end()){
                    medist[dutymap[pii(y,x)]] = dist;
                }
                for(int i=0;i<4;i++){
                    int ny = y + dy[i];
                    int nx = x + dx[i];
                    if(ny < 0 or ny >= h or nx < 0 or nx >= w) continue;
                    if(field[ny][nx] != 'x'){
                        q.push(State(ny,nx,dist+1));
                    }
                }
            }
        }
        vector<vector<int> > D(duty.size(),vector<int>(duty.size(),INF));
        for(int d=0;d<duty.size();d++){
            queue<State> q;
            q.push(State(duty[d].first,duty[d].second,0));
            vector<vector<char> > used(h,vector<char>(w,false));
            while(not q.empty()){
                int y = q.front().y;
                int x = q.front().x;
                int dist = q.front().dist;
                q.pop();
                if(used[y][x]) continue;
                used[y][x] = true;
                if(dutymap.find(pii(y,x)) != dutymap.end()){
                    D[d][dutymap[pii(y,x)]] = dist;
                }
                for(int i=0;i<4;i++){
                    int ny = y + dy[i];
                    int nx = x + dx[i];
                    if(ny < 0 or ny >= h or nx < 0 or nx >= w) continue;
                    if(field[ny][nx] != 'x'){
                        q.push(State(ny,nx,dist+1));
                    }
                }
            }
        }
        // for(int i=0;i<duty.size();i++) D[i][i] = 0;
        // for(int k=0;k<duty.size();k++){
        //     for(int i=0;i<duty.size();i++){
        //         for(int j=0;j<duty.size();j++){
        //             D[i][j] = min(D[i][j],D[i][k]+D[k][j]);
        //         }
        //     }
        // }
        bool ok = true;
        for(int i=0;i<duty.size();i++){
            if(medist[i] == INF) ok = false;
        }
        for(int i=0;i<duty.size();i++){
            for(int j=0;j<duty.size();j++){
                if(D[i][j] == INF) ok = false;
            }
        }
        if(ok){
            int N = duty.size();
            vector<vector<int> > DP(1 << N,vector<int>(N,INF));
            for(int i=0;i<N;i++){
                DP[1 << i][i] = medist[i];
            }

            for(int s=0;s < (1 << N);s++){
                for(int now=0;now<N;now++){
                    if(DP[s][now] == INF) continue;
                    for(int k=0;k<N;k++){
                        if(s & (1 << k))  continue;
                        DP[s | (1 << k)][k] = min(DP[s | (1 << k)][k],DP[s][now]+D[now][k]);
                    }
                }
            }

            int mini = INF;
            for(int i=0;i<N;i++){
                mini = min(mini,DP[(1<<N)-1][i]);
            }
            cout << mini << endl;
        }else{
            cout << -1 << endl;
        }
    }
    return 0;
}

Measured memory_bytes: 1284