#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<climits>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<memory>
#include<functional>

using namespace std;

#define ALL(g) (g).begin(),(g).end()
#define REP(i, x, n) for(int i = x; i < n; i++)
#define rep(i,n) REP(i,0,n)
#define F(i,j,k) fill(i[0],i[0]+j*j,k)
#define P(p) cout<<(p)<<endl;
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define INF 1<<25
#define pb push_back

typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<double> vd;
typedef pair<int,int> pii;
typedef pair<long,long> pll;
typedef long long ll;

using namespace std;

struct robot {
    int x, y, cost, dust;

    bool operator >(const robot& r) const {
        return cost > r.cost;
    }
};

int main()
{
    int w, h;
    while (cin >> w >> h, w|h) {
        // input
        vector<string> v;
        rep(j, h){
            string input;
            cin >> input;
            v.pb(input);
        }

        // dust map
        int dust[20][20];
        fill_n((int *)dust, 20 * 20, 0);
        int bit = 1;

        // start & goal
        int sx, sy;
        int goal = 0;
        rep(j, h){
            rep(i, w){
                if(v[j][i] == 'o') {
                    sx = i; sy = j;
                }
                if(v[j][i] == '*') {
                    dust[j][i] = bit;
                    goal += bit;
                    bit *= 2;
                }
            }
        }

        // bfs
        int check[20][20][1<<10];
        fill_n((int *)check, 20*20*(1<<10), INT_MAX);
        int cost = -1;
        priority_queue<robot, vector<robot>, greater<robot> > q;
        q.push((robot){sx, sy, 0, 0});
        while(!q.empty()){
            robot p = q.top(); q.pop();
            // goal
            if (p.dust == goal) {
                cost = p.cost;
                break;
            }
            // up
            if (p.y - 1 >= 0 && v[p.y-1][p.x] != 'x') {
                if (v[p.y-1][p.x] == '*' && (p.dust & dust[p.y-1][p.x]) != dust[p.y-1][p.x]) {
                    if (check[p.y-1][p.x][p.dust + dust[p.y-1][p.x]] > p.cost + 1) {
                        q.push((robot){p.x, p.y-1, p.cost+1, p.dust + dust[p.y-1][p.x]});
                        check[p.y-1][p.x][p.dust + dust[p.y-1][p.x]] = p.cost + 1;
                    }
                } else {
                    if (check[p.y-1][p.x][p.dust] > p.cost + 1) {
                        q.push((robot){p.x, p.y-1, p.cost+1, p.dust});
                        check[p.y-1][p.x][p.dust] = p.cost + 1;
                    }
                }
            }
            // down
            if (p.y + 1 < h && v[p.y+1][p.x] != 'x') {
                if (v[p.y+1][p.x] == '*' && (p.dust & dust[p.y+1][p.x]) != dust[p.y+1][p.x]) {
                    if (check[p.y+1][p.x][p.dust + dust[p.y+1][p.x]] > p.cost + 1) {
                        q.push((robot){p.x, p.y+1, p.cost+1, p.dust + dust[p.y+1][p.x]});
                        check[p.y+1][p.x][p.dust + dust[p.y+1][p.x]] = p.cost + 1;
                    }
                } else {
                    if (check[p.y+1][p.x][p.dust] > p.cost + 1) {
                        q.push((robot){p.x, p.y+1, p.cost+1, p.dust});
                        check[p.y+1][p.x][p.dust] = p.cost + 1;
                    }
                }
            }
            // right
            if (p.x + 1 < w && v[p.y][p.x+1] != 'x') {
                if (v[p.y][p.x+1] == '*' && (p.dust & dust[p.y][p.x+1]) != dust[p.y][p.x+1]) {
                    if (check[p.y][p.x+1][p.dust + dust[p.y][p.x+1]] > p.cost + 1) {
                        q.push((robot){p.x+1, p.y, p.cost+1, p.dust + dust[p.y][p.x+1]});
                        check[p.y][p.x+1][p.dust + dust[p.y][p.x+1]] = p.cost + 1;
                    }
                } else {
                    if (check[p.y][p.x+1][p.dust] > p.cost + 1) {
                        q.push((robot){p.x+1, p.y, p.cost+1, p.dust});
                        check[p.y][p.x+1][p.dust] = p.cost + 1;
                    }
                }
            }
            // left
            if (p.x - 1 >= 0 && v[p.y][p.x-1] != 'x') {
                if (v[p.y][p.x-1] == '*' && (p.dust & dust[p.y][p.x-1]) != dust[p.y][p.x-1]) {
                    if (check[p.y][p.x-1][p.dust + dust[p.y][p.x-1]] > p.cost + 1) {
                        q.push((robot){p.x-1, p.y, p.cost+1, p.dust + dust[p.y][p.x-1]});
                        check[p.y][p.x-1][p.dust + dust[p.y][p.x-1]] = p.cost + 1;
                    }
                } else {
                    if (check[p.y][p.x-1][p.dust] > p.cost + 1) {
                        q.push((robot){p.x-1, p.y, p.cost+1, p.dust});
                        check[p.y][p.x-1][p.dust] = p.cost + 1;
                    }
                }
            }
        }
        cout << cost << endl;
    }

    return 0;
}

Measured memory_bytes: 2968