#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
using namespace std;

typedef vector <string> VS;
typedef pair <int, int> Position;
typedef map <Position, int> Index;

const int size = 21;
int w, h;
bool O[size][size];
bool V[size][size][1<<10];
Position D[size];
int DC;
Index ID;
int goal;

void init() {
    goal = 0;
    ID.clear();
    DC = 0;
    for ( int i = 0; i < size; i++ ) {
        for ( int j = 0; j < size; j++ ) {
            O[i][j] = false;
            for ( int k = 0; k < 1<<10; k++ ) {
                V[i][j][k] = false;
            }
        }
    }
}

typedef pair <int, int> PII;
typedef pair <PII, PII> Node;
typedef priority_queue <Node, vector<Node>, greater<Node> > Queue;
const int dr[4] = { 0, 0, 1, -1 };
const int dc[4] = { 1, -1, 0, 0 };

int solve( int sr, int sc ) {
    Queue Q;
    Node start( PII( 0, 0 ), PII( sr, sc ) );
    Q.push( start );
    V[sr][sc][0] = true;

    while ( !Q.empty() ) {
        Node node = Q.top();
        Q.pop();

        int cost = node.first.first;
        int dirt = node.first.second;
        Position pos = node.second;

        if ( dirt == (1<<goal)-1 ) {
            return cost;
        }

        for ( int i = 0; i < 4; i++ ) {
            int nCost = cost + 1;
            Position nPos = pos;
            nPos.first += dr[i];
            nPos.second += dc[i];

            if ( nPos.first < 0 || nPos.first >= h || nPos.second < 0 || nPos.second >= w ) {
                continue;
            }
            if ( O[nPos.first][nPos.second] ) {
                continue;
            }

            int nDirt = dirt;
            if ( ID.find( nPos ) != ID.end() ) {
                int id = ID[nPos];
                if ( ( nDirt & ( 1<<id ) ) == 0 ) {
                    nDirt = nDirt | ( 1<<id );
                }
            }

            if ( V[nPos.first][nPos.second][nDirt] ) {
                continue;
            }
            V[nPos.first][nPos.second][nDirt] = true;

            Node nNode( PII( nCost, nDirt ), nPos );
            Q.push( nNode );
        }
    }

    return -1;
}

int main() {
    while ( cin >> w >> h ) {
        if ( w == 0 && h == 0 ) break;
        init();

        VS lines(h);
        for ( int i = 0; i < h; i++ ) {
            cin >> lines[i];
        }
        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                if ( lines[i][j] == 'x' ) {
                    O[i][j] = true;
                }
            }
        }
        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                if ( lines[i][j] == '*' ) {
                    ID[Position( i, j )] = DC;
                    D[DC++] = Position( i, j );
                    goal++;
                }
            }
        }
        int sr, sc;
        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                if ( lines[i][j] == 'o' ) {
                    sr = i;
                    sc = j;
                }
            }
        }

        cout << solve( sr, sc ) << endl;
    }
    return 0;
}

Measured memory_bytes: 1600