#include <iostream>
#include <tuple>
#include <vector>
#include <queue>
#include <algorithm>

char stage[20][20];
int cost[1024][10];
int dis[10][10];
int w, h;

typedef std::tuple<int, int, int> T;
std::vector<T> pos_to_num;

long long unsigned PopCount(long long unsigned x) {
	x = (x & 0x5555555555555555ULL) + ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
	x = (x & 0x3333333333333333ULL) + ((x & 0xCCCCCCCCCCCCCCCCULL) >> 2);
	x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x & 0xF0F0F0F0F0F0F0F0ULL) >> 4);

	x *= 0x0101010101010101ULL;

	return x;
}

void dijkstra(int sx, int sy)
{
	int c[20][20] = {0};
	int dx[4] = {1, -1, 0, 0};
	int dy[4] = {0, 0, 1, -1};

	for ( int i = 0; i < 20; ++i ) {
		for ( int j = 0; j < 20; ++j ) {
			c[i][j] = 0xfffff;
		}
	}

	std::queue<std::tuple<int,int>> q;
	q.push(std::make_tuple(sx, sy));
	c[sx][sy] = 0;

	while(!q.empty()) {
		auto a = q.front(); q.pop();
		int x = std::get<0>(a);
		int y = std::get<1>(a);
		for ( int i = 0; i < 4; ++i ) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if ( nx < 0 || nx >= w ) continue;
			if ( ny < 0 || ny >= h ) continue;
			if ( stage[nx][ny] == 'x' ) continue;

			if ( c[nx][ny] > (c[x][y] + 1) ) {
				c[nx][ny] = c[x][y] + 1;
				q.push(std::make_tuple(nx, ny));
			}
		}
	}

	if ( stage[sx][sy] == 'o' ) {
		for ( int i = 0; i < pos_to_num.size(); ++i ) {
			cost[(1<<std::get<2>(pos_to_num[i]))][std::get<2>(pos_to_num[i])] = c[std::get<0>(pos_to_num[i])][std::get<1>(pos_to_num[i])];
		}
	} else if ( stage[sx][sy] == '*' ) {
		int num;
		for ( int i = 0; i < pos_to_num.size(); ++i ) {
			if ( sx == std::get<0>(pos_to_num[i]) && sy == std::get<1>(pos_to_num[i]) ) {
				num = std::get<2>(pos_to_num[i]);
			}
		}
		for ( int i = 0; i < pos_to_num.size(); ++i ) {
			dis[num][std::get<2>(pos_to_num[i])] = c[std::get<0>(pos_to_num[i])][std::get<1>(pos_to_num[i])];
		}
	}
}

int main()
{
	while ( true ) {
		for ( int i = 0; i < 1024; ++i ) {
			for ( int j = 0; j < 10; ++j ) {
				cost[i][j] = 0xfffff;
			}
		}
		for ( int i = 0; i < 10; ++i ) {
			for ( int j = 0; j < 10; ++j ) {
				dis[i][j] = 0xfffff;
			}
		}
		for ( int i = 0; i < 20; ++i ) {
			for ( int j = 0;j < 20; ++j ) {
				stage[i][j] = 0;
			}
		}

		std::cin >> w >> h;
		if ( w == 0 && h == 0 ) return 0;
 
		int sx, sy;
		int k = 0;
		for ( int i = 0; i < h; ++i ) {
			for ( int j = 0; j < w; ++j ) {
				std::cin >> stage[j][i];
				if ( stage[j][i] == '*' ) {
					pos_to_num.push_back(T(j, i, k));
					k++;
				}
				if ( stage[j][i] == 'o' ) {
					sx = j; sy = i;
				}
			}
		}

		dijkstra(sx, sy);
		for ( auto &v: pos_to_num ) {
			dijkstra(std::get<0>(v), std::get<1>(v));
		}
		std::vector<std::tuple<int, int>> table(1<<k);
		for ( int i = 0; i < (1<<k); ++i ) {
			table[i] = std::make_tuple(PopCount(i), i);
		}
		std::sort(table.begin(), table.end());

		for ( int i = 0; i < (1<<k); ++i ) {
			int q = std::get<1>(table[i]);
			for ( int j = 0; j < k; ++j ) {
				if ( q & (1<<j) ) {
					for ( int l = 0; l < k; ++l ) {
						if ( (q ^ (1<<j)) & (1<<l) ) {
							int c = cost[q^(1<<j)][l] + dis[l][j];
							cost[q][j] = (c < cost[q][j]) ? c : cost[q][j];
						}
						//std::cout << "state:" << q << " to:" << j << " cost:" << cost[q][j] << std::endl;
					}
				}
			}
		}
		int min = 0xfffff;
		for ( int i = 0; i < k; ++i ) {
			if ( min > cost[(1<<k)-1][i] ) min = cost[(1<<k)-1][i];
		}
		if ( min == 0xfffff ) {
			std::cout << -1 << std::endl;
		} else {
			std::cout << min << std::endl;
		}
	}


	return 0;
}

Measured memory_bytes: 3264