#include<bits/stdc++.h>
using namespace std;
#define INF 1e9

int di[4] = {0, -1, 0, 1};
int dj[4] = {1, 0, -1, 0};

int w, h, si, sj, gi, gj, n;

int dist[11][11];
/* メモ再帰 */

int dp[(1<<20) + 1][21]; // dpテーブルは余裕をもったサイズにする
int rec(int bit, int v)
{
    // すでに探索済みだったらリターン
    if (dp[bit][v] != -1) return dp[bit][v];

    // 初期値
    if (bit == (1<<v)) {
        if(v != 0) return dp[bit][v] = INF;
        else return dp[bit][v] = 0;
    }

    // 答えを格納する変数
    int res = INF;

    // bit の v を除いたもの
    int prev_bit = bit & ~(1<<v);

    // v の手前のノードとして u を全探索
    for (int u = 0; u < n; ++u) {
        if (!(prev_bit & (1<<u))) continue; // u が prev_bit になかったらダメ

        // 再帰的に探索
        if (res > rec(prev_bit, u) + dist[u][v]) {
            res = rec(prev_bit, u) + dist[u][v];
        }
    }

    return dp[bit][v] = res; // メモしながらリターン
}


int bfs(vector<vector<bool> > canGo){

//まず最初にsの情報をキューに追加して、盤面を埋める
    queue<pair<int, pair<int, int> > > wait;
    wait.push(make_pair(0, make_pair(si, sj)));
    canGo[si][sj] = false;

    //以下、幅優先
    int ans = INF;   //ansを-1で初期化

    while(!wait.empty()){    //キュー画空になるまで
        //キューの先頭要素を取り出す
        int nowcost = wait.front().first;
        int nowi = wait.front().second.first;
        int nowj = wait.front().second.second;

        wait.pop();

        //ゴールにたどり着いたらそのコストが答え
        if(nowi == gi && nowj == gj){
            ans = nowcost;
            break;
        }

        //四方向を探索
        for(int k = 0; k < 4; k++){
            int nexti = nowi + di[k];
            int nextj = nowj + dj[k];

            //その方向に進めるなら
            if(canGo[nexti][nextj]){
                //そのマスにキューを追加し
                //再度検索することのないように壁で埋める
                wait.push(make_pair(nowcost + 1, make_pair(nexti, nextj)));
                canGo[nexti][nextj] = false;
            }
        }
    }

    //出力
    
    return ans;

}

int main(){

    while(1){
        cin >> w >> h;
        if(!w) break;

        vector<pair<int, int> > s;
        s.push_back({0, 0});
        vector<vector<bool> > a(h + 2, vector<bool> (w + 2, false));
        for(int i = 1; i <= h; i++){
            for(int j = 1; j <= w; j++){
                char input; cin >> input;
                if(input == 'x') continue;
                else{
                    a[i][j] = true;

                    if(input == 'o'){
                        s[0].first = i;
                        s[0].second = j;
                    }else if(input == '*'){
                        s.push_back({i, j});
                    }
                }
            }
        }

        n = s.size();
        
        //vector<vector<int> > dist(v, vector<int> (v));
        for(int k = 0; k < n; k++){
            for(int l = 0; l <= k; l++){

                //cout << k << " " << l << endl;
                if(k == l) dist[k][l] = 0;
                else{
                    si = s[k].first;
                    sj = s[k].second;
                    gi = s[l].first;
                    gj = s[l].second;

                    dist[k][l] = bfs(a);
                    dist[l][k] = dist[k][l];

                }
            }
        }
    


        /*cout << "ok"<< endl;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                cout << dist[i][j] << " ";
            }
            cout << endl;
        }*/

        // テーブルを全部 -1 にしておく (-1 でなかったところは探索済)
        for (int bit = 0; bit < (1<<n); ++bit) for (int v = 0; v < n; ++v) dp[bit][v] = -1;

        // 探索
        int res = INF;
        for (int v = 0; v < n; ++v) {
            if (res > rec((1<<n)-1, v)) {
                res = rec((1<<n)-1, v);
            }
        }


        if(res >= INF) cout << -1 << endl;
        else cout << res << endl;
    }
    return 0;
}


Measured memory_bytes: 3212