#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define lengthof(array) (sizeof(array) / sizeof(*array))
#define dump(a) (cerr << (#a) << " = " << (a) << endl)
#define FOR(it,c) for(__typeof((c).begin())it=(c).begin(); it!=(c).end();++it)
#define RFOR(it,c) for(__typeof((c).rbegin())it=(c).rbegin(); it!=(c).rend();++it)

template<class T> inline void chmax(T& a, const T& b) { if(b > a) a = b; }
template<class T> inline void chmin(T& a, const T& b) { if(b < a) a = b; }

template<typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os << '(' << p.first << ", " << p.second << ')';
	return os;
}

template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
	copy(v.begin(), v.end(), ostream_iterator<T>(os, " "));
	return os;
}

#define X first
#define Y second

const int INF = 0xfffffff;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};
const int MAX_N = 10;

int w, h;
int n;
vector<vector<int> > mat;
vector<int> x, y;
vector<string> field;
int memo[MAX_N + 1][1 << MAX_N];

int bfs(int from, int to) {
	vector<vector<int> > label(h, vector<int>(w, INF));
	queue<pair<int, int> > que;
	que.push(make_pair(x[from], y[from]));
	label[y[from]][x[from]] = 0;

	while(!que.empty()) {
		const int cx = que.front().X, cy = que.front().Y;
		que.pop();

		for(int i = 0; i < 4; ++i) {
			const int nx = cx + dx[i], ny = cy + dy[i];
			if(nx < 0 || ny < 0 || nx >= w || ny >= h || field[ny][nx] == 'x')
				continue;

			if(label[ny][nx] > label[cy][cx] + 1) {
				label[ny][nx] = label[cy][cx] + 1;
				que.push(make_pair(nx, ny));
			}
		}
	}

	return label[y[to]][x[to]];
}

int dfs(int cur, int visited) {
	if(visited == (1 << n) - 1)
		return 0;

	if(memo[cur][visited] != -1)
		return memo[cur][visited];

	int res = INF;
	for(int i = 0; i < n; ++i) {
		if(visited & (1 << i))
			continue;
		
		chmin(res, dfs(i, visited | (1 << i)) + mat[cur][i]);
	}

	return memo[cur][visited] = res;
}



int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	while(cin >> w >> h, w) {
		x.clear();
		y.clear();

		field.clear();
		field.resize(h);
		for(int i = 0; i < h; ++i)
			cin >> field[i];

		for(int i = 0; i < h; ++i) {
			for(int j = 0; j < w; ++j) {
				if(field[i][j] == '*') {
					x.push_back(j);
					y.push_back(i);
				}
			}
		}

		n = x.size();

		for(int i = 0; i < h; ++i) {
			for(int j = 0; j < w; ++j) {
				if(field[i][j] == 'o') {
					x.push_back(j);
					y.push_back(i);
					break;
				}
			}
		}

		mat.clear();
		mat.resize(n + 1, vector<int>(n + 1, INF));
		for(int i = 0; i <= n; ++i)
			mat[i][i] = 0;

		for(int i = 0; i < n; ++i)
			for(int j = i + 1; j <= n; ++j)
				mat[i][j] = mat[j][i] = bfs(i, j);

		memset(memo, -1, sizeof(memo));
		const int ans = dfs(n, 0);
		cout << (ans >= INF ? -1 : ans) << endl;		
	}

	return EXIT_SUCCESS;
}

Measured memory_bytes: 1304