#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
//#define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define RFOR(i, a, b) for (int i = (int)(b - 1); i >= (int)(a); --i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define RREP(i, n) for (int i = (int)(n - 1); i >= 0; --i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(a) ((int)(a).size())
#define BIT(x, i) (((x) >> (i)) & 1)
#define SQ(x) ((x) * (x))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define X first
#define Y second
#define INF 100000000

struct P {
    int from, cost;
    int trashes;

    bool operator >(const P& p) const {
        return cost > p.cost;
    }
};

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

int W, H;
char field[20][20];

int bfs(pii start, pii goal) {
    vvb G(H, vb(W));
    queue<pii> que;
    pii sentry = {-1, -1};
    que.push(start);
    que.push(sentry);
    int cnt = 0;
    while (!que.empty()) {
        pii p = que.front(); que.pop();
        if (p.X == goal.X && p.Y == goal.Y) {
            return cnt;
        }
        if (p == sentry) {
            if (que.empty()) break;
            que.push(sentry);
            cnt++;
            continue;
        }

        REP(i, 4) {
            int sx = p.X + dx[i], sy = p.Y + dy[i];
            if (0 <= sx && sx < W && 0 <= sy && sy < H && field[sy][sx] != 'x') {
                if (!G[sy][sx]) {
                    G[sy][sx] = true;
                    que.push({sx, sy});
                }
            }
        }
    }
    return 0;
}

int main() {
    while (cin >> W >> H, W|H) {
        pii start;
        vector<pii> trash;
        REP(y, H) REP(x, W) {
            cin >> field[y][x];
            switch (field[y][x]) {
            case 'o':
                start = {x, y};
                break;
            case '*':
                trash.push_back({x, y});
                break;
            }
        }

        vvi G(11, vi(1<<10, INF));

        int n = SZ(trash);
        vvi E(n+1, vi(n+1));
        REP(i, n) {
            E[n][i] = E[i][n] = bfs(start, trash[i]);
            FOR(j, i+1, n) {
                E[i][j] = E[j][i] = bfs(trash[i], trash[j]);
            }
        }

        priority_queue<P, vector<P>, greater<P>> que;
        que.push({n, 0, (1<<n)-1});
        G[n][(1<<n)-1] = 0;
        while (!que.empty()) {
            P p = que.top(); que.pop();
            if (p.trashes == 0) {
                cout << p.cost << endl;
                goto END;
            }

            REP(to, SZ(E[p.from])) {
                if (E[p.from][to] == 0) continue;
                int cost = p.cost + E[p.from][to];
                int trashes = p.trashes & ~(1 << to);
                if (G[to][trashes] > cost) {
                    G[to][trashes] = cost;
                    que.push({to, cost, trashes});
                }
            }
        }
        cout << -1 << endl;
END: {}
    }
}

Measured memory_bytes: 3188