Problem:
Problem F:
Cleaning Robot
Here, we want to solve path planning for a mobile robot cleaning a
rectangular room floor with furniture.
Consider the room floor paved with square tiles whose size fits 
the cleaning robot (1 × 1).
There are 'clean tiles' and 'dirty tiles', and the robot can change
a 'dirty tile' to a 'clean tile' by visiting the tile.
Also there may be some obstacles (furniture) whose size fits a
tile in the room. If there is an obstacle on a tile, the robot cannot visit 
it.
The robot moves to an adjacent tile with one move.
The tile onto which the robot moves must be one of four tiles 
(i.e., east, west, north or south) adjacent to the tile where the 
robot is present. The robot may visit a tile twice or more.
Your task is to write a program which computes the minimum number of
moves for the robot to change all 'dirty tiles' to 'clean tiles', 
if ever possible.
Input
The input consists of multiple maps, each representing the size 
and arrangement of the room. A map is given in the following format.
w h
c
11
c
12
c
13
...
c
1
w
c
21
c
22
c
23
...
c
2
w
...
c
h
1
c
h
2
c
h
3
...
c
hw
The integers
w
and
h
are the lengths of the two sides 
of the floor of the room in terms of widths of floor tiles.
w
and
h
are less than or equal to 20. The character
c
yx
represents 
what is initially on the tile with coordinates (
x, y
) as follows.
'
.
' : a clean tile
'
*
' : a dirty tile
'
x
' : a piece of furniture (obstacle)
'
o
' : the robot (initial position)
In the map the number of 'dirty tiles' does not exceed 10.
There is only one 'robot'.
The end of the input is indicated by a line containing two zeros.
Output
For each map, your program should output a line containing the minimum 
number of moves. If the map includes 'dirty tiles' which the robot cannot reach, 
your program should output -1.
Sample Input
7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
0 0
Output for the Sample Input
8
49
-1

Submitted solutions:

code_snippet: // clang-format off
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define stoi stoll
#define Endl endl
#define itn int
#define fi first
#define se second
#define rep(i, n) for(int i=0, i##_len=(n); i<i##_len; i++)
#define rep2(i, a, b) for (int i = (int)(a), i##_len=(b); i < i##_len; i++)
#define rep3(i, a, b) for (int i = (int)(a), i##_len=(b); i >= i##_len; i--)
#define FOR(i, a) for (auto &i: a)
#define ALL(obj) begin(obj), end(obj)
#define _max(x) *max_element(ALL(x))
#define _min(x) *min_element(ALL(x))
#define _sum(x) accumulate(ALL(x), 0LL)
#define LOWER_BOUND(A, key) distance(begin(A), lower_bound(ALL(A), key))
#define UPPER_BOUND(A, key) distance(begin(A), upper_bound(ALL(A), key))

const int MOD   = 1000000007;
// const int MOD    = 998244353;
const int INF    = (int)(1e13 + 7);
const double EPS = 1e-8;
const double PI  = 3.14159265358979;
template <class T> using V = vector<T>;
template <class T> using VV = vector<vector<T>>;
template <class T> using VVV = vector<vector<vector<T>>>;
template <class T, class S>  using P = pair<T, S>;
template<class T> bool chmax(T &a, const T &b) {if (a < b) {a = b;return true;}return false;}
template<class T> bool chmin(T &a, const T &b) {if (b < a) {a = b;return true;}return false;}
int _ceil(int a, int b) { return (a >= 0 ? (a + (b - 1)) / b : (a - (b - 1)) / b); }
int _mod(int &a) {a = a >= 0 ? a % MOD : a - (MOD * _ceil(a, MOD));return a;}
int _pow(int a, int b) {int res = 1;for (a %= MOD; b; a = a * a % MOD, b >>= 1)if (b & 1) res = res * a % MOD;return res;}
struct mint {long long x;mint(long long x = 0) : x((x % MOD + MOD) % MOD) {}mint operator-() const { return mint(-x); }mint &operator+=(const mint a) {if ((x += a.x) >= MOD) x -= MOD;return *this;}mint &operator-=(const mint a) {if ((x += MOD - a.x) >= MOD) x -= MOD;return *this;}mint &operator*=(const mint a) { (x *= a.x) %= MOD;return *this; }mint operator+(const mint a) const { return mint(*this) += a; }mint operator-(const mint a) const { return mint(*this) -= a; } mint operator*(const mint a) const { return mint(*this) *= a; }mint pow(long long t) const {if (!t) return 1;mint a = pow(t >> 1);a *= a;if (t & 1) a *= *this;return a;}mint inv() const { return pow(MOD - 2); }mint &operator/=(const mint a) { return *this *= a.inv(); }mint operator/(const mint a) const { return mint(*this) /= a; }};istream &operator>>(istream &is, mint &a) { return is >> a.x; }ostream &operator<<(ostream &os, const mint &a) { return os << a.x; }
// clang-format on

int now;
void process(int x_now, int y_now, int prev_cost, deque<P<int, int>> &pos, VV<int> &grid, V<string> &c, V<P<int, int>> &nodes, VV<int> &shortest_path) {
  if (c[x_now][y_now] != 'x' and grid[x_now][y_now] > prev_cost + 1) {
    grid[x_now][y_now] = prev_cost + 1;
    pos.emplace_back(x_now, y_now);
    if (c[x_now][y_now] == '*' or c[x_now][y_now] == 'o') {
      rep(i, nodes.size()) if (nodes[i].fi == x_now and nodes[i].se == y_now) {
        shortest_path[now][i] = prev_cost + 1;
      }
    }
  }
}

signed main() {
  cin.tie(nullptr);
  cout.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(15);
  while (1) {
    int w, h;
    cin >> w >> h;
    if (w == 0) break;
    V<string> c(h + 2);
    c[0]     = string(w + 2, 'x');
    c[h + 1] = string(w + 2, 'x');
    rep(i, h) {
      cin >> c[i + 1];
      c[i + 1] = 'x' + c[i + 1] + 'x';
    }
    V<P<int, int>> nodes;
    rep(i, h) rep(j, w) if (c[i + 1][j + 1] == 'o') nodes.emplace_back(i + 1, j + 1);
    rep(i, h) rep(j, w) if (c[i + 1][j + 1] == '*') nodes.emplace_back(i + 1, j + 1);
    int n = nodes.size();
    VV<int> shortest_path(n, V<int>(n, INF));
    rep(i, n) shortest_path[i][i] = 0;
    rep(i, n) {
      now               = i;
      P<int, int> start = nodes[i];
      VV<int> grid(h + 2, V<int>(w + 2, INF));
      grid[start.fi][start.se] = 0;
      deque<P<int, int>> pos   = {start};
      while (pos.size()) {
        process(pos[0].fi + 1, pos[0].se, grid[pos[0].fi][pos[0].se], pos, grid, c, nodes, shortest_path);
        process(pos[0].fi - 1, pos[0].se, grid[pos[0].fi][pos[0].se], pos, grid, c, nodes, shortest_path);
        process(pos[0].fi, pos[0].se + 1, grid[pos[0].fi][pos[0].se], pos, grid, c, nodes, shortest_path);
        process(pos[0].fi, pos[0].se - 1, grid[pos[0].fi][pos[0].se], pos, grid, c, nodes, shortest_path);
        pos.pop_front();
      }
    }
    bool yes = true;
    rep(i, n) rep(j, n) if (shortest_path[i][j] == INF) {
      yes = false;
    }
    if (!yes) {
      cout << -1 << endl;
      continue;
    }
    VV<int> dp((1 << n), V<int>(n, INF));
    dp[1][0] = 0;
    rep(i, (1 << n) - 1) {
      rep(j, n) {
        rep(k, n) {
          if (((i >> k) & 1) == 0) {
            if (__builtin_popcount(i | (1 << k)) == 1) continue;
            dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k], dp[i][j] + shortest_path[j][k]);
          }
        }
      }
    }
    int ans = INF;
    rep(i, n) {
      chmin(ans, dp[(1 << n) - 1][i]);
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3416
final_rank: 2

code_snippet: #include<bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using lll = __int128;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

vector<ll> dx={1,0,-1,0,-1,-1,1,1,0},dy={0,1,0,-1,-1,1,-1,1,0};

bool solve(){
    ll W,H;cin>>W>>H;
    if(W+H==0) return 0;
    vector<string> S(H);rep(i,H) cin>>S[i];
    vector<vector<vvll>> dist(H,vector(W,vector(H,vector(W,-1ll))));
    rep(i,H) rep(j,W){
        if(S[i][j]!='o'&&S[i][j]!='*') continue;
        dist[i][j][i][j]=0;
        queue<P> q;
        q.push({i,j});
        while(q.size()){
            auto [nowi,nowj]=q.front();q.pop();
            rep(k,4){
                ull toi=nowi+dx[k],toj=nowj+dy[k];
                if(!(toi<H&&toj<W)) continue;
                if(dist[i][j][toi][toj]!=-1||S[toi][toj]=='x') continue;
                dist[i][j][toi][toj]=dist[i][j][nowi][nowj]+1;
                q.push({toi,toj});
            }
        }
        rep(i2,H) rep(j2,W) if(dist[i][j][i2][j2]==-1) dist[i][j][i2][j2]=INF;
    }

    vector<P> A;rep(i,H) rep(j,W) if(S[i][j]=='o') A.push_back({i,j});
                rep(i,H) rep(j,W) if(S[i][j]=='*') A.push_back({i,j});

    ll N=A.size();
    vvll dp(1<<N,vll(N,INF));
    dp[0][0]=0;
    rep(bit,1<<N) rep(j,N){
        if(bit==0){
            chmin(dp[1][0],dp[bit][j]);
            continue;
        }
        rep(k,N){
            if((bit>>j&1)==0||(bit>>k&1)) continue;
            chmin(dp[bit|(1<<k)][k],dp[bit][j]+dist[A[j].first][A[j].second][A[k].first][A[k].second]);
        }
    }


    ll ans=INF;
    rep(i,N) chmin(ans,dp[(1<<N)-1][i]);
    cout << (ans==INF?-1:ans) << endl;
    return 1;
}



int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(solve());
}
accuracy: 1
time_ms: 70
memory_kb: 4824
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0 && W == 0) return false;
    vector<string> S(H);
    int sr = -1, sc = -1;
    vector<vector<int>> dust(H, vector<int>(W, -1));
    int N = 0;
    for (int i = 0; i < H; i++) {
        cin >> S[i];
        for (int j = 0; j < W; j++) {
            if (S[i][j] == 'o') sr = i, sc = j;
            if (S[i][j] == '*') dust[i][j] = N++;
        }
    }
    vector<vector<vector<int>>> dist(1 << N, vector<vector<int>>(H, vector<int>(W, 1 << 30)));
    dist[0][sr][sc] = 0;
    queue<tuple<int, int, int>> q;
    q.emplace(0, sr, sc);
    int D[5] = {0, 1, 0, -1, 0};
    while (q.size()) {
        auto [b, r, c] = q.front();
        q.pop();
        for (int d = 0; d < 4; d++) {
            int nr = r + D[d], nc = c + D[d + 1];
            if (0 <= nr && nr < H && 0 <= nc && nc < W && S[nr][nc] != 'x') {
                int nb = b;
                if (dust[nr][nc] != -1) nb |= 1 << dust[nr][nc];
                if (dist[nb][nr][nc] > dist[b][r][c] + 1) {
                    dist[nb][nr][nc] = dist[b][r][c] + 1;
                    q.emplace(nb, nr, nc);
                }
            }
        }
    }
    int ans = 1 << 30;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            ans = min(ans, dist[(1 << N) - 1][i][j]);
        }
    }
    if (ans == 1 << 30) ans = -1;
    cout << ans << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 100
memory_kb: 4736
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int INF = 2e9;
int dx[]          = {-1, 0, 1, 0};
int dy[]          = {0, 1, 0, -1};

void solve(int w, int h, vector<vector<char>> grid) {
    int sx = -1, sy = -1;
    vector<pair<int, int>> tiles;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (grid[i][j] == 'o') {
                sx = i;
                sy = j;
            }
            if (grid[i][j] == '*') {
                tiles.emplace_back(i, j);
            }
        }
    }
    ranges::sort(tiles);

    vector dist(h, vector(w, vector(h, vector(w, INF))));
    auto bfs = [&](const int start_x, const int start_y) {
        queue<pair<int, int>> q;
        dist[start_x][start_y][start_x][start_y] = 0;
        q.emplace(start_x, start_y);
        while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop();
            for (int dir = 0; dir < 4; dir++) {
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if (nx < 0 || nx >= h || ny < 0 || ny >= w) {
                    continue;
                }
                if (grid[nx][ny] == 'x') {
                    continue;
                }
                if (dist[start_x][start_y][nx][ny] == INF) {
                    dist[start_x][start_y][nx][ny] = dist[start_x][start_y][x][y] + 1;
                    q.emplace(nx, ny);
                }
            }
        }
    };

    bfs(sx, sy);
    for (auto [start_x, start_y] : tiles) {
        bfs(start_x, start_y);
    }

    const int n = static_cast<int>(tiles.size());
    int ans     = INF;
    do {
        int sum   = 0;
        int cur_x = sx;
        int cur_y = sy;
        bool ok   = true;
        for (int i = 0; i < n; i++) {
            auto [next_x, next_y] = tiles[i];
            if (dist[cur_x][cur_y][next_x][next_y] == INF) {
                ok = false;
                break;
            }
            sum += dist[cur_x][cur_y][next_x][next_y];
            cur_x = next_x;
            cur_y = next_y;
        }
        if (ok) {
            ans = min(ans, sum);
        }
    } while (next_permutation(tiles.begin(), tiles.end()));

    cout << (ans == INF ? -1 : ans) << endl;
}

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

        vector<vector<char>> c(h, vector<char>(w));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                cin >> c[i][j];
            }
        }
        solve(w, h, c);
    }
}
accuracy: 1
time_ms: 230
memory_kb: 4608
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int INF = 2e9;
int dx[]          = {-1, 0, 1, 0};
int dy[]          = {0, 1, 0, -1};

void solve(int w, int h, vector<vector<char>> grid) {
    int sx = -1, sy = -1;
    vector<pair<int, int>> tiles;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (grid[i][j] == 'o') {
                sx = i;
                sy = j;
            }
            if (grid[i][j] == '*') {
                tiles.emplace_back(i, j);
            }
        }
    }
    tiles.insert(tiles.begin(), {sx, sy});

    vector dist(h, vector(w, vector(h, vector(w, INF))));
    auto bfs = [&](const int start_x, const int start_y) {
        queue<pair<int, int>> q;
        dist[start_x][start_y][start_x][start_y] = 0;
        q.emplace(start_x, start_y);
        while (!q.empty()) {
            auto [x, y] = q.front();
            q.pop();
            for (int dir = 0; dir < 4; dir++) {
                int nx = x + dx[dir];
                int ny = y + dy[dir];
                if (nx < 0 || nx >= h || ny < 0 || ny >= w) {
                    continue;
                }
                if (grid[nx][ny] == 'x') {
                    continue;
                }
                if (dist[start_x][start_y][nx][ny] == INF) {
                    dist[start_x][start_y][nx][ny] = dist[start_x][start_y][x][y] + 1;
                    q.emplace(nx, ny);
                }
            }
        }
    };

    for (auto [start_x, start_y] : tiles) {
        bfs(start_x, start_y);
    }

    const int n = static_cast<int>(tiles.size());
    vector dp(1 << n, vector(h, vector(w, INF)));
    dp[1 << 0][sx][sy] = 0;
    for (int bit = 0; bit < (1 << n); bit++) {
        for (int i = 0; i < n; i++) {
            auto [x, y] = tiles[i];
            if (!(bit & (1 << i))) {
                continue;
            }
            if (dp[bit][x][y] == INF) {
                continue;
            }

            for (int j = 0; j < n; j++) {
                auto [nx, ny] = tiles[j];
                if (dist[x][y][nx][ny] == INF) {
                    continue;
                }
                if (!(bit & (1 << j))) {
                    int next_bit         = bit | (1 << j);
                    dp[next_bit][nx][ny] = min(dp[next_bit][nx][ny], dp[bit][x][y] + dist[x][y][nx][ny]);
                }
            }
        }
    }

    int ans = INF;
    for (auto [i, j] : tiles) {
        ans = min(ans, dp[(1<<n)-1][i][j]);
    }
    cout << (ans == INF ? -1 : ans) << endl;
}

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

        vector<vector<char>> c(h, vector<char>(w));
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                cin >> c[i][j];
            }
        }
        solve(w, h, c);
    }
}
accuracy: 1
time_ms: 80
memory_kb: 6736
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define loop(n) for (int tjh = 0; tjh < (int)(n); tjh++)
constexpr int maxh=20;constexpr int maxg=10;
constexpr int ma=10000;
constexpr array<array<int,2>,4>moves={-1,0,0,-1,0,1,1,0};
signed main() {
  cin.tie(0)->sync_with_stdio(0);//NOLINT
  cout<<fixed<<setprecision(16);
  int w,h;array<string,maxh>c;
  vector<array<int,2>>g;
  array<array<int,maxh>,maxh>d;
  array<array<int,maxg+1>,maxg+1>dists;
  queue<array<int,2>>q;
  array<array<int,maxg>,(1<<maxg)>dp;
  int res;
  g.reserve(maxg+1);
  for (;cin>>w>>h,w;) {
    g.resize(0);
    rep(i,h) cin>>c[i];
    rep(i,h)rep(j,w)if (c[i][j]=='o')g.push_back({i,j});
    rep(i,h)rep(j,w)if (c[i][j]=='*')g.push_back({i,j});
    if ((int)g.size()==1){cout<<0<<'\n';continue;}
    rep(i,g.size()) {
      rep(j,h)rep(k,w)d[j][k]=ma;
      d[g[i][0]][g[i][1]]=0;
      q.push(g[i]);
      for (;!q.empty();) {
        array<int,2> a=q.front();
        q.pop();
        for (auto j:moves) {
          array<int,2>b={a[0]+j[0],a[1]+j[1]};
          if (b[0]<0||b[0]>=h||b[1]<0||b[1]>=w)continue;
          if (c[b[0]][b[1]]=='x')continue;
          if (d[b[0]][b[1]]!=ma)continue;
          d[b[0]][b[1]]=d[a[0]][a[1]]+1;
          q.push(b);
        }
      }
      rep(j,g.size())dists[i][j]=d[g[j][0]][g[j][1]];
    }

    rep(i,1<<(g.size()-1))rep(j,g.size()-1)dp[i][j]=ma;
    for (int i=1;i<(1<<(g.size()-1));i++) {
      rep(j,g.size()-1) {
        if (!(i&(1<<j))) continue;
        int i0=i^(1<<j);
        if (!i0) {
          dp[i][j]=dists[0][j+1];
          break;
        }
        rep(k,g.size()-1) {
          if (!(i0&(1<<k))) continue;
          int t=dp[i0][k]+dists[k+1][j+1];
          if (t<dp[i][j])dp[i][j]=t;
        }
      }
    }
    res=*min_element(dp[(1<<(g.size()-1))-1].begin(),dp[(1<<(g.size()-1))-1].begin()+g.size()-1);
    cout<<(res==ma?-1:res)<<'\n';
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

vvll bfs(ll h, ll w, vs a, ll sx, ll sy){
    vvll dist(h,vll(w,1LL<<30));
    queue<pll> d;
    dist[sx][sy] = 0;
    d.push({sx,sy});
    vpll dxy = {{-1,0},{1,0},{0,-1},{0,1}};
    while(!d.empty()){
        auto [x,y] = d.front();
        d.pop();
        for(auto [dx,dy]:dxy){
            ll tx = x+dx;
            ll ty = y+dy;
            if(0 <= tx && tx < h && 0 <= ty && ty < w){
                if(dist[tx][ty] > dist[x][y] + 1 && a[tx][ty] != 'x'){
                    dist[tx][ty] = dist[x][y] + 1;
                    d.push({tx,ty});
                }
            }
        }
    }
    return dist;
}

void solve(ll h, ll w, vs a){
    ll sx,sy;
    vpll b;
    vll idx;
    vvvll dist;
    rep(i,h){
        rep(j,w){
            if(a[i][j] == 'o'){
                sx = i;
                sy = j;
            }
            if(a[i][j] == '*'){
                idx.push_back(len(b));
                b.push_back({i,j});
                dist.push_back(bfs(h,w,a,i,j));
            }
        }
    }
    ll ans = 1LL<<60;
    //print(dist[0]);
    do{
        ll temp = 0;
        ll x = sx;
        ll y = sy;
        //print(idx);
        rep(i,len(idx)){
            ll tx = b[idx[i]].first;
            ll ty = b[idx[i]].second;
            temp += dist[idx[i]][x][y];
            //print(tx,ty,x,y,dist[idx[i]][x][y]);
            x = tx;
            y = ty;
        }
        ans = min(ans,temp);
    }while(next_permutation(all(idx)));
    print(ans>=(1<<30)?-1:ans);
}

int main(){
    while(1){
        LL(w,h);
        if(w == 0 && h == 0){break;}
        VS(a,h);
        solve(h,w,a);
    }
}
accuracy: 1
time_ms: 160
memory_kb: 3584
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;

const vector<int> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1};

void solve(int w, int h) {
    vector<string> c(h);
    for (auto &i: c) cin >> i;
    map<pair<int, int>, int> mp;
    int cnt = 0;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (c[i][j] == 'o') {
                mp[make_pair(i, j)] = 0;
            }
            if (c[i][j] == '*') {
                mp[make_pair(i, j)] = ++cnt;
            }
        }
    }
    constexpr int inf = 1 << 29;
    vector dist(cnt + 1, vector(h, (vector<int>(w, inf))));
    queue<tuple<int, int, int>> q;
    for (const auto [t, num]: mp) {
        dist[num][t.first][t.second] = 0;
        q.emplace(num, t.first, t.second);
    }
    while(!q.empty()) {
        auto [s, x, y] = q.front();
        q.pop();
        for (int k = 0; k < 4; k++) {
            int nx = x + dx[k], ny = y + dy[k];
            if (0 <= nx && nx < h && 0 <= ny && ny < w && c[nx][ny] != 'x' && dist[s][nx][ny] == inf) {
                dist[s][nx][ny] = dist[s][x][y] + 1;
                q.emplace(s, nx, ny);
            }
        }
    }
    vector mat(cnt + 1,vector<int>(cnt + 1));
    for (const auto [t, num]: mp) {
        for (const auto [r, num2]: mp) {
            mat[num][num2] = dist[num][r.first][r.second];
        }
    }
    int ans = inf;
    vector<int> order(cnt);
    for (int i = 0; i < cnt; i++) order[i] = i + 1;
    do {
        int k = 0;
        bool valid = true;
        for (int i = 0; i < cnt; i++) {
            if (i == 0) {
                if (mat[0][order[i]] == inf) valid = false;
                else k += mat[0][order[i]];
            }
            else {
                if (mat[order[i - 1]][order[i]] == inf) valid = false;
                else k += mat[order[i - 1]][order[i]];
            }
        }
        if(valid) ans = min(ans, k);
    }while(next_permutation(order.begin(), order.end()));
    cout << (ans == inf? -1: ans) << endl;
}

int main() {
    int w, h;
    cin >> w >> h;
    do {
        solve(w, h);
        cin >> w >> h;
    }while(w != 0);
}
accuracy: 1
time_ms: 240
memory_kb: 3232
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
vector<int> dx = {0,1,0,-1};
vector<int> dy = {1,0,-1,0};
const int mod = 1000000007;
const int inf = 1<<24;

int main(){
    //ios::sync_with_stdio(false);
    //cin.tie(0);
    while (1){
        int W,H;
        cin >> W >> H;
        if (W == 0 && H == 0){
            return 0;
        }
        vector<string> data = vector<string>(H);
        for (int i = 0; i < H;i++){
            cin >> data[i];
        }
        int cnt = 0;
        int sh,sw;
        map<pair<int,int>,int> mp;
        for (int i = 0; i < H;i++){
            for (int j = 0; j < W;j++){
                if (data[i][j] == 'o'){
                    sh = i;
                    sw = j;
                }
                if (data[i][j] == '*'){
                    mp[make_pair(i,j)] = cnt;
                    cnt++;
                }
            }
        }

        vector<vector<int>> D = vector<vector<int>>(cnt,vector<int>(cnt,inf));
        vector<int> E = vector<int>(cnt,inf);
        for (auto [k, v] : mp){
            auto [h, w] = k;
            int idx1 = v;
            vector<vector<int>> dist = vector<vector<int>>(H,vector<int>(W,-1));
            queue<pair<int,int>> que;
            dist[h][w] = 0;
            que.push(make_pair(h,w));

            while (!que.empty()){
                auto[h, w] = que.front();
                que.pop();
                for (int i = 0; i < 4;i++){
                    int nh,nw;
                    nh = h+dx[i];
                    nw = w+dy[i];
                    if (nh < 0 or nw < 0 or nh >= H or nw >= W) continue;
                    if (data[nh][nw] == 'x') continue;
                    if (dist[nh][nw] != -1) continue;
                    dist[nh][nw] = dist[h][w]+1;
                    if (data[nh][nw] == '*'){
                        int idx2 = mp[make_pair(nh,nw)];
                        D[idx1][idx2] = dist[nh][nw];
                        D[idx2][idx1] = dist[nh][nw];
                    }
                    if (nh == sh && nw == sw){
                        E[idx1] = dist[nh][nw];
                    }
                    que.push(make_pair(nh,nw));
                }
            }

            //debug
            /*
            cout << h << ' ' << w << endl;
            for (int i = 0; i < H;i++){
                for (int j = 0; j < W;j++){
                    cout << dist[i][j] << ' ';
                }
                cout << endl;
            }
            */


        }

        vector<vector<int>> dp = vector<vector<int>>(1<<cnt,vector<int>(cnt,inf));
        for (int i = 0; i < cnt;i++){
            dp[1<<i][i] = E[i];
        }

        for (int b = 1; b < 1<<cnt;b++){
            if (__builtin_popcount(b) == 1){
                continue;
            }
            for (int v = 0; v < cnt;v++){
                if (b>>v&1){
                    int nb = b^(1<<v);
                    for (int u = 0; u < cnt;u++){
                        if (nb>>u&1){
                            dp[b][v] = min(dp[b][v],dp[nb][u]+D[u][v]);
                        }
                    }
                }
            }
        }

        int ans = inf;
        for (int i = 0; i < cnt;i++){
            ans = min(ans,dp[(1<<cnt)-1][i]);
        }
        cout << (ans == inf ? -1 : ans) << endl;
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3412
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef long double ld;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
#define F first
#define S second
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    while(1){
        ll W,H;cin>>W>>H;
        if(!W)return 0;
        vector<string>S(H);
        REP(i,H)cin>>S[i];
        vector<pi>A;
        REP(i,H)REP(j,W)if(S[i][j]=='o')A.emplace_back(pi(i,j));
        REP(i,H)REP(j,W)if(S[i][j]=='*')A.emplace_back(pi(i,j));
        if(A.size()==1){cout<<0<<endl;continue;}
        ll M=A.size();
        vvi D(M,vi(M));
        REP(i,M){
            vvi d(H,vi(W,1e18));
            d[A[i].F][A[i].S]=0;
            priority_queue<pi>Q;
            Q.emplace(A[i]);
            while(!Q.empty()){
                auto[x,y]=Q.top();Q.pop();
                if(x&&S[x-1][y]!='x'&&d[x-1][y]>d[x][y]+1)d[x-1][y]=d[x][y]+1,Q.emplace(pi(x-1,y));
                if(x+1<H&&S[x+1][y]!='x'&&d[x+1][y]>d[x][y]+1)d[x+1][y]=d[x][y]+1,Q.emplace(pi(x+1,y));
                if(y&&S[x][y-1]!='x'&&d[x][y-1]>d[x][y]+1)d[x][y-1]=d[x][y]+1,Q.emplace(pi(x,y-1));
                if(y+1<W&&S[x][y+1]!='x'&&d[x][y+1]>d[x][y]+1)d[x][y+1]=d[x][y]+1,Q.emplace(pi(x,y+1));
            }
            REP(j,M)D[i][j]=d[A[j].F][A[j].S];
        }
        vvi T(M,vi(1<<M,1e18));
        FOR(i,1,M)T[i][1+(1<<i)]=D[0][i];
        FOR(j,1,1<<M)FOR(i,1,M)if((j>>i)%2){
            FOR(k,1,M)if((j>>k)%2==0)chmin(T[k][j+(1<<k)],T[i][j]+D[i][k]);
        }
        ll ans=1e18;
        REP(i,M)chmin(ans,T[i].back());
        if(ans>1e17)cout<<-1<<endl;
        else cout<<ans<<endl;      
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3488
final_rank: 4

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2,popcnt")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using Bint = mp::cpp_int;
// using Bdouble = mp::number<mp::cpp_dec_float<256>>;
// Bdouble Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(Bdouble a, Bdouble b) { return mp::fabs(a - b) < Beps; }

#define pb emplace_back
#define int ll
#define endl '\n'
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
// #define next asdnext
// #define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;

const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int() {
        return dist_x(rng);
    }
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;

namespace bit_function {
    using i64 = ll;
    // using i64 = uint64_t;
    // bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
    i64 lrmask(int l, int r) { return (1LL << r) - (1LL << l); }
    i64 sub_bit(i64 x, int l, int r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
    i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }
    
    i64 popcount(i64 x) { return __builtin_popcountll(x); }
    i64 popcount(i64 x, int l, int r) { return __builtin_popcountll(sub_bit(x, l, r)); }
    i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); } // 最上位bitより下のみ
    i64 unpopcount(i64 x, int l, int r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); } // 最上位bitより上も含まれうる
    bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; } // xが負のときは常にfalse
    bool is_pow4(i64 x) { return __builtin_popcountll(x) == 1 && __builtin_ctz(x) % 2 == 0; }
    //bool is_pow4(ll x) { return __builtin_popcountll(x) == 1 && (x&0x55555555); }
    
    int top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
    int bot_bit(i64 x) { return __builtin_ctzll(x);} // 2^kの位 (x > 0)
    int next_bit(i64 x, int k) { // upper_bound
        x >>= (k + 1);
        int pos = k + 1;
        while (x > 0) {
            if (x & 1) return pos;
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int prev_bit(i64 x, int k) {
        // k = min(k, bit_width(x)); ?
        int pos = 0;
        while (x > 0 && pos < k) {
            if (x & 1) {
                if (pos < k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    int kth_bit(i64 x, int k) { // kは1-indexed
        int pos = 0, cnt = 0;
        while (x > 0) {
            if (x & 1) {
                cnt++;
                if (cnt == k) return pos;
            }
            x >>= 1;
            pos++;
        }
        return -1;
    }
    i64 msb(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
    i64 lsb(i64 x) { return (x & -x); } // mask
    
    int countl_zero(i64 x) { return __builtin_clzll(x); }
    int countl_one(i64 x) { // countl_oneと定義が異なるので注意
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { k--; ret++; }
        return ret;
    }
    int countr_zero(i64 x) { return __builtin_ctzll(x); } // x=0のとき64
    int countr_one(i64 x) { int ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }
    // int countr_one(ll x) { return __builtin_popcount(x ^ (x & -~x));

    i64 l_one(i64 x) { // 最上位で連なってる1のmask
        if (x == 0) return 0;
        i64 ret = 0, k = 63 - __builtin_clzll(x);
        while (k != -1 && (x & (1LL << k))) { ret += 1LL << k; k--; }
        return ret;
    }
    
    int floor_log2(i64 x) { return 63 - __builtin_clzll(x); } // top_bit
    int ceil_log2(i64 x) { return 64 - __builtin_clzll(x - 1); }
    i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // msb
    i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }
    
    i64 rotl(i64 x, int k) { // 有効bit内でrotate. オーバーフロー注意
        i64 w = bit_width(x); k %= w;
        return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
    i64 rotr(i64 x, int k) {
        i64 w = bit_width(x); k %= w;
        return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
    }
    // i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
    i64 bit_reverse(i64 x) { // 有効bit内で左右反転
        i64 r = 0, w = bit_width(x);
        for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
        return r;
    }
    // i64 bit_reverse(i64 x, int l, int r) {}
    
    bool is_palindrome(i64 x) { return x == bit_reverse(x); }
    bool is_palindrome(i64 x, int l, int r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
    i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
    i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット
    
    i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
    i64 hamming(i64 a, i64 b, int l, int r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
    i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
    i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
    i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数
    
    i64 next_combination(i64 x) {
        i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzll(x) + 1));
    }
} using namespace bit_function;

namespace util_function {
    namespace Std = std;
    __int128_t POW(__int128_t x, int n) {
        __int128_t ret = 1;
        assert(n >= 0);
        if (x == 1 or n == 0) ret = 1;
        else if (x == -1 && n % 2 == 0) ret = 1; 
        else if (x == -1) ret = -1; 
        else if (n % 2 == 0) {
            // assert(x < INFL);
            ret = POW(x * x, n / 2);
        } else {
            // assert(x < INFL);
            ret = x * POW(x, n - 1);
        }
        return ret;
    }
    int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
        assert(y != 0);
        if (x >= 0 && y > 0) return x / y;
        if (x >= 0 && y < 0) return x / y - (x % y < 0);
        if (x < 0 && y < 0) return x / y + (x % y < 0);
        return x / y - (x % y < 0); //  (x < 0 && y > 0) 
    }
    int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
        assert(y != 0);
        return x - y * per(x, y);
    } // https://yukicoder.me/problems/no/2781
    int floor(int x, int y) { // (ld)x / y 以下の最大の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x >= 0 ? x / y : (x + 1) / y - 1;
    }
    int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
        assert(y != 0);
        if (y < 0) x = -x, y = -y;
        return x > 0 ? (x - 1) / y + 1 : x / y;
    }
    int round(int x, int y) { // (ld)(x/y)を小数点第1位について四捨五入
        assert(y != 0);
        return (x * 2 + y) / (y * 2);
    }
    int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
        assert(y != 0 && k >= 0);
        if (k == 0) return (x * 2 + y) / (y * 2);
        x /= y * POW(10, k - 1);
        if (x % 10 >= 5) return (x + 10 - x % 10) * POW(10, k - 1);
        return x * POW(10, k - 1);
    }
    int round2(int x, int y) { // 五捨五超入 // 未verify
        assert(y != 0);
        if (y < 0) y = -y, x = -x;
        int z = x / y;
        if ((z * 2 + 1) * y <= y * 2) z++;
        return z;
    }
    ld round(ld x, int k) { // xを10^kの位に関して四捨五入. to_string(x, k)優先
        // x += EPS;
        ld d = pow(10, -k);
        return Std::round(x * d) / d;
    }
    ld floor(ld x, int k) { // xを10^kの位に関してflooring
        // x += EPS;
        ld d = pow(10, -k);
        return Std::floor(x * d) / d; // 未verify
    }
    ld ceil(ld x, int k) { // xを10^kの位に関してceiling
        // x -= EPS;
        ld d = pow(10, -k);
        return Std::ceil(x * d) / d; // 未verify
    }
    // int kth(int x, int y, int k) { // x / yの10^kの位の桁
    // }
    int floor(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return Std::floor(x / y);
        // floor(x) = ceil(x - 1) という話も
    }
    int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
        assert(!equals(y, 0));
        return Std::ceil(x / y);
        // ceil(x) = floor(x + 1)
    }
    int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
        // 未verify. 誤差対策TODO. EPS外してもいいかも。
        assert(!equals(y, 0));
        if (x >= 0 && y > 0) return Std::floor(x / y)+EPS;
        if (x >= 0 && y < 0) return -Std::floor(x / fabs(y));
        if (x < 0 && y < 0) return Std::floor(x / y) + (x - Std::floor(x/y)*y < -EPS);
        return Std::floor(x / y) - (x - Std::floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
    }
    ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
        // 未verify. 誤差対策TODO. -0.0が返りうる。
        assert(!equals(y, 0));
        if (x >= 0) return x - fabs(y)*fabs(per(x, y));
        return x - fabs(y)*floor(x, fabs(y));
    }
    int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
    int modf(ld x) {
        if (x < 0) return ceill(x);
        else return floorl(x);
    }
    // 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
    int seisuu(int x, int y) {
        assert(y != 0);
        return x / y;
    }
    int seisuu(ld x, ld y) { // 誤差対策TODO
        assert(!equals(y, 0));
        return (int)(x / y);
    }

    int floor_log(int base, int x) {
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now <= x) {
            now *= base;
            if (now <= x) ret++;
        }
        return ret;
    }
    int ceil_log(int base, int x) {
        assert(base >= 2);
        int ret = 0, now = 1;
        while (now < x) {
            now *= base;
            ret++;
        }
        return ret;
    }

    template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
        return b;
    }
    template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
        if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
        return b;
    }
    
    template <class T> bool chmax(T &a, const T& b) {
        if (a < b) { a = b; return true; } return false;
    }
    template <class T> bool chmin(T &a, const T& b) {
        if (a > b) { a = b; return true; } return false;
    }
    template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
        return a + b + c - Std::max({a, b, c}) - Std::min({a, b, c});
    }
    template <class T> void Sort(T &a, T &b, bool rev = false) { 
        if (rev == false) if (a > b) swap(a, b);
        else if (b > a) swap(b, a);
    }
    template <typename T, typename... Args>
    void Sort(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.begin(), vec.end());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }
    template <typename T, typename... Args>
    void Sortr(T& a, T& b, T& c, Args&... args) {
        vector<T> vec = {a, b, c, args...};
        sort(vec.rbegin(), vec.rend());
        auto it = vec.begin();
        a = *it++; b = *it++; c = *it++;
        int dummy[] = { (args = *it++, 0)... };
        static_cast<void>(dummy);
    }

    istream &operator >>(istream &is, __int128_t& x) {
        string S; is >> S;
        __int128_t ret = 0;
        int f = 1;
        if (S[0] == '-') f = -1; 
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9')
                ret = ret * 10 + S[i] - '0';
        x = ret * f;
        return (is);
    }
    ostream &operator <<(ostream &os, __int128_t x) {
        ostream::sentry s(os);
        if (s) {
            __uint128_t tmp = x < 0 ? -x : x;
            char buffer[128]; char *d = end(buffer);
            do {
                --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
            } while (tmp != 0);
            if (x < 0) { --d; *d = '-'; }
            int len = end(buffer) - d;
            if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
        }
        return os;
    }
    
    __int128_t stoll(string &S) {
        __int128_t ret = 0; int f = 1;
        if (S[0] == '-') f = -1; 
        for (int i = 0; i < S.length(); i++)
            if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
        return ret * f;
    }
    __int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
    __int128_t lcm(__int128_t a, __int128_t b) {
        return a / gcd(a, b) * b;
        // lcmが__int128_tに収まる必要あり
    }
    
    string to_string(ld x, int k) { // xの小数第k位までをstring化する
        assert(k >= 0);
        stringstream ss;
        ss << setprecision(k + 2) << x;
        string s = ss.str();
        if (s.find('.') == string::npos) s += '.';
        int pos = s.find('.');
        for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
        s.pop_back();
        if (s.back() == '.') s.pop_back();
        return s;
    
        // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
        // ss << setprecision(k + 1) << x;
        // string s = ss.str();
        // if (s.find('.') == string::npos) s += '.';
        // int pos = s.find('.');
        // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
        // if (s.back() == '.') s.pop_back();
        // return s;
    }
    string to_string(__int128_t x) {
        string ret = "";
        if (x < 0) { ret += "-"; x *= -1; }
        while (x) { ret += (char)('0' + x % 10); x /= 10; }
        reverse(ret.begin(), ret.end());
        return ret;
    }
    string to_string(char c) { string s = ""; s += c; return s; }
} using namespace util_function;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};

template<typename T>
class Compress { // 試験運用, バグったらTをintにする
public:
    int sz = 0;
    // gp_hash_table<T, int, custom_hash> Z;
    // gp_hash_table<int, T, custom_hash> UZ;
    unordered_map<T, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, T> UZ;   // 圧縮した値 -> 元の値
 
    Compress() {}
    Compress(const vector<T> &V, T base = 0) {
        this->sz = base;
        set<T> s(V.begin(), V.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<T> &V1, const vector<T> &V2, T base = 0) {
        this->sz = base;
        vector<T> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<T> s(V3.begin(), V3.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<T> &V1, const vector<T> &V2, const vector<T> &V3, T base = 0) {
        this->sz = base;
        vector<T> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<T> s(V4.begin(), V4.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<T> &V1, const vector<T> &V2,
            const vector<T> &V3, const vector<T> &V4, T base = 0) {
        this->sz = base;
        vector<T> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<T> s(V5.begin(), V5.end());
 
        for (T x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<T> &V) {
        vector<int> ret(V.size());
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[V[i]];
        }
        return ret;
    }
 
    vector<T> unzip(const vector<int> &V) {
        vector<T> ret(V.size());
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[V[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    T encode(int x) { return Z[x]; }
    int decode(T x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
#pragma endregion

// グラフ(隣接リスト)とターミナル頂点集合を渡す
// 始点や終点が非固定ならそれも渡す
int TSP(const vector<vector<Edge>> &G, vector<int> &V, int s = -1, int t = -1) {
    int N = G.size(); // Gの頂点数
    int K = V.size(); // ターミナル頂点数

    vector<vector<int>> dist(K, vector<int>(K, INFL));
    for (int i = 0; i < K; i++) {
        vector<int> D(N, INFL);
        D[V[i]] = 0;
        
        std::priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
        pq.emplace(0, V[i]);
        
        while (pq.size()) {
            int d = pq.top().first;
            int v = pq.top().second;
            pq.pop();
            
            if (d > D[v]) continue;
            for (auto &e : G[v]) {
                if (D[e.to] > D[v] + e.cost) {
                    D[e.to] = D[v] + e.cost;
                    pq.emplace(D[e.to], e.to);
                }
            }
        }

        for (int j = 0; j < K; j++) {
            dist[i][j] = D[V[j]];
        }
    }
    
    // dp[i][j] := 頂点sから出発して訪問頂点の集合がiであり、最後に頂点jにいる
    //             ときの移動距離の最小値
    vector<vector<int>> dp(1LL << K, vector<int>(K, INFL));

    if (s == -1) { // 始点非固定
        for (int i = 0; i < K; i++) {
            dp[1 << i][i] = 0;
        }
    } else {
        int s2 = -1;
        for (int i = 0; i < K; i++) {
            if (V[i] == s) {
                s2 = i;
                break;
            }
        }
        assert(s2 != -1);
        s = s2;
        dp[1 << s][s] = 0;
    }

    for (int i = 0; i < (1LL << K); i++) { // 全ての集合(状態)を小さい順に見る
        if (s != -1 && !(i & (1 << s))) continue; // 始点を含んでいないならとばす
        
        for (int j = 0; j < K; j++) { // 移動元としてあり得る都市を探し、
            if (dp[i][j] == INFL) continue;
            if (!(i & (1 << j))) continue;

            for (int k = 0; k < K; k++) { // 移動先の都市を探す
                if (i & (1LL << k)) continue; // 集合iに都市kが含まれてるならとばす

                int d = dist[j][k];
                dp[i + (1LL << k)][k] = min(dp[i + (1LL << k)][k], dp[i][j] + d);
            }
        }
    }

    if (t == -1) { // 終点非固定
        int ans = INFL;
        for (int i = 0; i < K; i++) {
            ans = min(ans, dp[(1 << K) - 1][i]);
        }

        if (ans == INFL) ans = -1;
        return ans;
    } else {
        if (dp[(1 << K) - 1][t] == INFL) dp[(1 << K) - 1][t] = -1;
        return dp[(1 << K) - 1][t];
    }
}

int H, W;
bool isvalid(int x, int y) {
    if (x >= 0 && x < H && y >= 0 && y < W) return true;
    else return false;
}

signed main() {
    while (cin >> W >> H, H) {
        vector<vector<char>> S(H, vector<char>(W));
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                cin >> S[i][j];
            }
        }

        int s;
        vector<int> V;
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (S[i][j] == 'o') {
                    s = i*W + j;
                    V.pb(s);
                    S[i][j] = '.';
                }

                if (S[i][j] == '*') {
                    int v = i*W + j;
                    V.pb(v);
                    S[i][j] = '.';
                }
            }
        }

        vector<vector<Edge>> G(H*W);
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (S[i][j] == 'x') continue;
                int v = i*W + j;

                for (int k = 0; k < 4; k++) {
                    int ni = i + dx[k];
                    int nj = j + dy[k];
                    if (!isvalid(ni, nj)) continue;
                    if (S[ni][nj] == 'x') continue;

                    int nv = ni*W + nj; 
                    G[v].pb(Edge(nv, 1));
                }
            }
        }

        // 隣接リスト, 訪問頂点列(, 始点, 終点)
        // {s, t} \in V の必要
        int ans = TSP(G, V, s);

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3552
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

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

vector<vector<ll>> DFS(vector<string>& S, int SX, int SY) {
    int N = S.size();
    int M = S[0].size();
    vector<vector<ll>> Ret(N, vector<ll>(M,inf));
    Ret[SX][SY] = 0;
    queue<pair<int,int>> Q;
    Q.push({SX, SY});
    while(!Q.empty()) {
        auto [X, Y] = Q.front();
        Q.pop();
        rep(i,0,4) {
            int NX = X + dx[i], NY = Y + dy[i];
            if (0 <= NX && NX < N && 0 <= NY & NY < M) {
                if (S[NX][NY] == '.' && Ret[NX][NY] == inf) {
                    Ret[NX][NY] = Ret[X][Y] + 1;
                    Q.push({NX,NY});
                }
            }
        }
    }
    return Ret;
}

int main() {
while(1) {
    int N, M;
    cin >> M >> N;
    if (N == 0 && M == 0) return 0;
    vector<string> S(N);
    rep(i,0,N) cin >> S[i];
    vector<int> SX, SY;
    rep(i,0,N) {
        rep(j,0,M) {
            if (S[i][j] == 'o') SX.push_back(i), SY.push_back(j), S[i][j] = '.';
        }
    }
    rep(i,0,N) {
        rep(j,0,M) {
            if (S[i][j] == '*') SX.push_back(i), SY.push_back(j), S[i][j] = '.';
        }
    }
    int L = SX.size();
    vector<vector<vector<ll>>> D(L);
    rep(i,0,L) D[i] = DFS(S, SX[i], SY[i]);
    ll ANS = inf;
    vector<int> ID(L-1);
    iota(ALL(ID),1);
    do {
        int Now = 0;
        ll COUNT = 0;
        rep(i,0,L-1) {
            COUNT += D[Now][SX[ID[i]]][SY[ID[i]]];
            Now = ID[i];
        }
        chmin(ANS, COUNT);
    } while(next_permutation(ALL(ID)));
    cout << (ANS == inf ? -1 : ANS) << endl;
}
}
accuracy: 1
time_ms: 150
memory_kb: 3524
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
const vector<int> dx = {1, 0, -1, 0};
const vector<int> dy = {0, 1, 0, -1};
const int INF = 1e9;
int main() {
  while (1) {
    int w, h;
    cin >> w >> h;
    if (w == 0 && h == 0) {
      break;
    }
    vector<string> c(h);
    for (int i = 0; i < h; i++) {
      cin >> c[i];
    }
    int sh = -1, sw = -1;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (c[i][j] == 'o') {
            sh = i;
            sw = j;
        }
      }
    }
    vector<vector<bool>> used(h, vector<bool> (w, false));
    queue<pair<int, int>> Q;
    Q.push(make_pair(sh, sw));
    while (!Q.empty()) {
      auto [vh, vw] = Q.front();
      Q.pop();
      used[vh][vw] = true;
      for (int d = 0; d < 4; d++) {
        int nh = vh + dx[d];
        int nw = vw + dy[d];
        if (nh < 0 || nh >= h || nw < 0 || nw >= w) continue;
        if (!used[nh][nw] && c[nh][nw] != 'x') {
          Q.push(make_pair(nh, nw));
          used[nh][nw] = true;
        }
      }
    }
    bool ok = true;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (c[i][j] == '*' && !used[i][j]) {
          ok = false;
        }
      }
    }
    if (!ok) {
      cout << -1 << endl;
      continue;
    }
    vector<pair<int, int>> id;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (c[i][j] == 'o') {
          c[i][j] = '.';
          id.push_back(make_pair(i, j));
        }
      }
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (c[i][j] == '*') {
          c[i][j] = '.';
          id.push_back(make_pair(i, j));
        }
      }
    }
    int N = id.size();
    vector<vector<int>> d2(N, vector<int> (N));
    for (int i = 0; i < N; i++) {
      vector<vector<int>> dist(h, vector<int> (w, INF));
      dist[id[i].first][id[i].second] = 0;
      Q.push(id[i]);
      while (!Q.empty()) {
        auto [vh, vw] = Q.front();
        Q.pop();
        for (int d = 0; d < 4; d++) {
          int nh = vh + dx[d];
          int nw = vw + dy[d];
          if (nh < 0 || nh >= h || nw < 0 || nw >= w) continue;
          if (c[nh][nw] != 'x' && dist[nh][nw] > dist[vh][vw] + 1) {
            dist[nh][nw] = dist[vh][vw] + 1;
            Q.push(make_pair(nh, nw));
          }
        }
      }
      for (int j = 0; j < N; j++) {
        if (i == j) continue;
        int nh = id[j].first;
        int nw = id[j].second;
        assert(dist[nh][nw] != INF);
        d2[i][j] = dist[nh][nw];
        d2[j][i] = dist[nh][nw];
      }
    }
    vector<int> ids(N);
    iota(ids.begin(), ids.end(), 0);
    int ans = INF;
    do {
      if (ids[0] != 0) break;
      int tmp = 0;
      for (int i = 1; i < N; i++) {
        tmp += d2[ids[i - 1]][ids[i]];
      }
      ans = min(ans, tmp);
    } while(next_permutation(ids.begin(), ids.end()));
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 100
memory_kb: 3456
final_rank: 9

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;

using ll = long long;
using i64 = long long;
using pll = pair<ll,ll>;
using plll = pair<pll,ll>;
using pii =pair<int,int>;

constexpr ll mod = 998244353;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int dX[4]={1,0,-1,0};
int dY[4]={0,-1,0,1};

//library


//end

int bfs(pii & s, pii &g, vector<string> & F){
    int h=F.size(),w=F[0].size();
    queue<pii> que;
    vector<vector<int>> dist(h,vector<int>(w,100000));
    que.push(s);
    dist[s.first][s.second]=0;
    while (que.size()){
        auto [x,y]=que.front();
        que.pop();
        for (int d=0; d<4; d++){
            int nx=x+dx[d], ny=y+dy[d];
            if (nx<0 || nx>=h || ny<0 || ny>=w )continue;
            if (F[nx][ny]=='x')continue;
            if (dist[nx][ny]>dist[x][y]+1){
                dist[nx][ny]=dist[x][y]+1;
                que.emplace(nx,ny);
            }
        }
    }
    //cout<<dist[g.first][g.second]<<' '<<s.first<<endl;
    return dist[g.first][g.second];


}


int main(){
    while (true){
        int w,h;
        cin>>w>>h;
        if (w==0)break;
        vector<string> F(h);
        for (int i=0; i<h; i++)cin>>F[i];
        map<int,pii> dic;
        int k=1;
        for (int i=0; i<h; i++){
            for (int j=0; j<w; j++){
                if (F[i][j]=='*'){
                    dic[k]=make_pair(i,j);
                    k++;
                }
                if (F[i][j]=='o') {
                    dic[0] = make_pair(i, j);
                    //cout<<i<<endl;
                }

            }
        }

        //cout<<dic[0].first<<endl;
        bool ok=true;
        vector<vector<int>> E(k,vector<int>(k));
        for (int i=0; i<k-1; i++){
            for (int j=i+1; j<k; j++){
                int dis=bfs(dic[i],dic[j],F);
                if (dis==100000){
                    ok=false;
                }
                E[i][j]=dis;
                E[j][i]=dis;
            }
        }

        if (ok==false){
            cout<<-1<<endl;
            continue;
        }

        vector<vector<int>> dp((1<<k),vector<int>(k,100000));
        dp[1][0]=0;
        for (int S=1; S<(1<<k); S++){
            for (int v=0; v<k; v++){
                if ((S&(1<<v))==0)continue;
                for (int u=0; u<k; u++){
                    if ((S&(1<<u))>0)continue;
                    dp[S+(1<<u)][u]=min(dp[S+(1<<u)][u],dp[S][v]+E[v][u]);
                }
            }
        }
        int ans=100000;
        for (int v=1; v<k; v++)ans=min(ans,dp[dp.size()-1][v]);
        cout<<ans<<endl;




    }

}
accuracy: 1
time_ms: 30
memory_kb: 3456
final_rank: 3

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using ll = long long;
#define MOD 1000000007
#define Mod 998244353
const int MAX = 1000000005;
const long long INF = 1000000000000000005LL;
using namespace std;
//using namespace atcoder;

int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};

bool solve() {
    int w, h;
    cin >> w >> h;
    if (w == 0 && h == 0) return false;
    vector<string> c(h);
    for (int i = 0; i < h; i++) cin >> c[i];
    vector<pair<int, int>> pos;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (c[i][j] == '*') pos.push_back({i, j});
        }
    }
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (c[i][j] == 'o') pos.push_back({i, j});
        }
    }
    int n = (int)pos.size();
    vector<vector<vector<int>>> dist(n, vector<vector<int>>(h, vector<int>(w, -1)));
    for (int i = 0; i < n; i++) {
        int si = pos[i].first, sj =  pos[i].second;
        dist[i][si][sj] = 0;
        queue<pair<int, int>> que;
        que.push({si, sj});
        while (que.size()) {
            auto [x, y] = que.front();
            que.pop();
            for (int k = 0; k < 4; k++) {
                int ni = x + di[k], nj = y + dj[k];
                if (ni < 0 || ni >= h || nj < 0 || nj >= w) continue;
                if (c[ni][nj] == 'x') continue;
                if (dist[i][ni][nj] != -1) continue;
                dist[i][ni][nj] = dist[i][x][y] + 1;
                que.push({ni, nj});
            }
        }
    }
    vector<int> vec(n-1);
    for (int i = 0; i < n-1; i++) vec[i] = i;
    int ans = MAX;
    do {
        auto [ti, tj] = pos[vec[0]];
        if (dist[n-1][ti][tj] == -1) continue;
        int cnt = dist[n-1][ti][tj];
        for (int i = 1; i < n-1; i++) {
            ti = pos[vec[i]].first; tj = pos[vec[i]].second;
            if (dist[vec[i-1]][ti][tj] == -1) {
                cnt = MAX;
                break;
            }
            cnt += dist[vec[i-1]][ti][tj];
        }
        ans = min(ans, cnt);
    } while(next_permutation(vec.begin(), vec.end()));
    cout << (ans == MAX ? -1 : ans) << endl;
    return true;
}

int main() {
    ios::sync_with_stdio(0); cin.tie();
    while (solve()) {}
}
accuracy: 1
time_ms: 160
memory_kb: 3560
final_rank: 13

code_snippet: #include<bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
vector<ll> dx={1,0,-1,0,-1,-1,1,1,0},dy={0,1,0,-1,-1,1,-1,1,0};

bool solve(){
    ll W,H;cin>>W>>H;
    if(H==0&&W==0) return 0;
    vector<string> S(H);rep(i,H) cin>>S[i];
    ll sx,sy;
    rep(i,H) rep(j,W) if(S[i][j]=='o') sx=i,sy=j;
    vector dist(H,vector<vvll>(W,vvll(H,vll(W,INF))));
    rep(i,H) rep(j,W){
        dist[i][j][i][j]=0;
        queue<P> q;
        q.push({i,j});
        while(q.size()){
            auto [nowi,nowj]=q.front();q.pop();
            rep(k,4){
                ull toi=nowi+dx[k],toj=nowj+dy[k];
                if(!(toi<H&&toj<W)) continue;
                if(S[toi][toj]=='x') continue;
                if(dist[i][j][toi][toj]!=INF) continue;
                dist[i][j][toi][toj]=dist[i][j][nowi][nowj]+1;
                q.push({toi,toj});
            }
        }
    }

    vll A(0);
    rep(i,H) rep(j,W) if(S[i][j]=='o') A.push_back(i*W+j);
    rep(i,H) rep(j,W) if(S[i][j]=='*') A.push_back(i*W+j);
    ll si=A.size();
    vvll dp(1<<si,vll(si,INF));
    dp[1][0]=0;
    rep(i,1<<si){
        rep(j,si) rep(k,si){
            if(!(i>>j&1)) continue;
            if(i>>k&1) continue;
            chmin(dp[i|(1<<k)][k],dp[i][j]+dist[A[j]/W][A[j]%W][A[k]/W][A[k]%W]);
   
        }
    }

    ll ans=INF;
    rep(i,si) chmin(ans,dp[(1<<si)-1][i]);
   
    cout << (ans==INF?-1:ans) << endl;
    return 1;
}




int main(){
   cin.tie(0);
   ios::sync_with_stdio(false);
   while(solve());
}
accuracy: 1
time_ms: 210
memory_kb: 4740
final_rank: 18

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2,popcnt")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using Bint = mp::cpp_int;
// using Bdouble = mp::number<mp::cpp_dec_float<256>>;
// Bdouble Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(Bdouble a, Bdouble b) { return mp::fabs(a - b) < Beps; }
 
#define pb emplace_back
#define int ll
#define endl '\n'
// #define unordered_map<int, int> gp_hash_table<int, int, custom_hash> 
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
#define next asdnext
#define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;
 
const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;
 
using i64 = ll;
// using i64 = uint64_t;
// bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
i64 lrmask(int l, int r) { return (1LL << r) - (1LL << l); }
i64 sub_bit(i64 x, int l, int r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }
 
i64 popcount(i64 x) { return __builtin_popcountll(x); }
i64 popcount(i64 x, int l, int r) { return __builtin_popcountll(sub_bit(x, l, r)); }
i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); }
i64 unpopcount(i64 x, int l, int r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); }
bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; } // xが負のときは常にfalse
bool is_pow4(i64 x) { return __builtin_popcount(x) == 1 && __builtin_ctz(x) % 2 == 0; }
 
int top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
int bot_bit(i64 x) { return __builtin_ctzll(x);} // 2^kの位 (x > 0)
int next_bit(i64 x, int k) { // upper_bound
    x >>= (k + 1);
    int pos = k + 1;
    while (x > 0) {
        if (x & 1) return pos;
        x >>= 1;
        pos++;
    }
    return -1;
}
int prev_bit(i64 x, int k) {
    // k = min(k, bit_width(x)); ?
    int pos = 0;
    while (x > 0 && pos < k) {
        if (x & 1) {
            if (pos < k) return pos;
        }
        x >>= 1;
        pos++;
    }
    return -1;
}
int kth_bit(i64 x, int k) { // kは1-indexed
    int pos = 0, cnt = 0;
    while (x > 0) {
        if (x & 1) {
            cnt++;
            if (cnt == k) return pos;
        }
        x >>= 1;
        pos++;
    }
    return -1;
}
i64 MSB(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
i64 LSB(i64 x) { return (x & -x); } // mask
 
int countl_zero(i64 x) { return __builtin_clzll(x); }
int countl_one(i64 x) {
    i64 ret = 0, k = 63 - __builtin_clzll(x);
    while (k != -1 && (x & (1LL << k))) { k--; ret++; }
    return ret;
}
int countr_zero(i64 x) { return __builtin_ctzll(x); } // x==0のとき64が返ることに注意
int countr_one(i64 x) { int ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }
 
int floor_log2(i64 x) { if (x == 0) return 0; return 63 - __builtin_clzll(x); } // top_bit
int ceil_log2(i64 x) { if (x == 0) return 0; return 64 - __builtin_clzll(x - 1); }
i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // MSB
i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }
 
i64 rotl(i64 x, int k) { // 有効bit内でrotate. オーバーフロー注意
    i64 w = bit_width(x); k %= w;
    return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
}
// i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
i64 rotr(i64 x, int k) {
    i64 w = bit_width(x); k %= w;
    return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
}
// i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
i64 bit_reverse(i64 x) { // 有効bit内で左右反転
    i64 r = 0, w = bit_width(x);
    for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
    return r;
}
// i64 bit_reverse(i64 x, int l, int r) { return 0; }
 
bool is_palindrome(i64 x) { return x == bit_reverse(x); }
bool is_palindrome(i64 x, int l, int r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット
 
i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
i64 hamming(i64 a, i64 b, int l, int r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数
 
i64 next_combination(i64 x) {
    i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzll(x) + 1));
}
 
 
__int128_t POW(__int128_t x, int n) {
    __int128_t ret = 1;
    assert(n >= 0);
    if (x == 1 or n == 0) ret = 1;
    else if (x == -1 && n % 2 == 0) ret = 1; 
    else if (x == -1) ret = -1; 
    else if (n % 2 == 0) {
        assert(x < INFL);
        ret = POW(x * x, n / 2);
    } else {
        assert(x < INFL);
        ret = x * POW(x, n - 1);
    }
    return ret;
}
int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
    assert(y != 0);
    if (x >= 0 && y > 0) return x / y;
    if (x >= 0 && y < 0) return x / y - (x % y < 0);
    if (x < 0 && y < 0) return x / y + (x % y < 0);
    return x / y - (x % y < 0); //  (x < 0 && y > 0) 
}
int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
    assert(y != 0);
    if (x >= 0) return x % y;
    __int128_t ret = x % y; // (x < 0)
    ret += (__int128_t)abs(y) * INFL;
    ret %= abs(y);
    return ret;
}
int floor(int x, int y) { // (ld)x / y 以下の最大の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x >= 0 ? x / y : (x + 1) / y - 1;
}
int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x > 0 ? (x - 1) / y + 1 : x / y;
}
int round(int x, int y) { // (ld)(x/y)を小数点第1位について四捨五入
    assert(y != 0);
    return (x * 2 + y) / (y * 2);
}
int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
    assert(y != 0 && k >= 0);
    if (k == 0) return (x * 2 + y) / (y * 2);
    x /= y * POW(10, k - 1);
    if (x % 10 >= 5) return (x + 10 - x % 10) * POW(10, k - 1);
    return x * POW(10, k - 1);
}
int round2(int x, int y) { // 五捨五超入 // 未verify
    assert(y != 0);
    if (y < 0) y = -y, x = -x;
    int z = x / y;
    if ((z * 2 + 1) * y <= y * 2) z++;
    return z;
}
ld round(ld x, int k) { // xを10^kの位に関して四捨五入. to_string(x, k)優先
    // x += EPS;
    ld d = pow(10, -k);
    return round(x * d) / d;
}
ld floor(ld x, int k) { // xを10^kの位に関してflooring
    // x += EPS;
    ld d = pow(10, -k);
    return floor(x * d) / d; // 未verify
}
ld ceil(ld x, int k) { // xを10^kの位に関してceiling
    // x -= EPS;
    ld d = pow(10, -k);
    return ceil(x * d) / d; // 未verify
}
// int kth(int x, int y, int k) { // x / yの10^kの位の桁
// }
int floor(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return floor(x / y);
    // floor(x) = ceil(x - 1) という話も
}
int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
    assert(!equals(y, 0));
    return ceil(x / y);
    // ceil(x) = floor(x + 1)
}
int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
    // 未verify. 誤差対策TODO. EPS外してもいいかも。
    assert(!equals(y, 0));
    if (x >= 0 && y > 0) return floor(x / y)+EPS;
    if (x >= 0 && y < 0) return -floor(x / fabs(y));
    if (x < 0 && y < 0) return floor(x / y) + (x - floor(x/y)*y < -EPS);
    return floor(x / y) - (x - floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
}
ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
    // 未verify. 誤差対策TODO. -0.0が返りうる。
    assert(!equals(y, 0));
    if (x >= 0) return x - fabs(y)*fabs(per(x, y));
    return x - fabs(y)*floor(x, fabs(y));
}
int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
int modf(ld x) {
	if (x < 0) return ceill(x);
	else return floorl(x);
}
// 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
int seisuu(int x, int y) {
    assert(y != 0);
    return x / y;
}
int seisuu(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return (int)(x / y);
}
 
template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
    return b;
}
template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
    return b;
}
 
template <class T> bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; } return false;
}
template <class T> bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; } return false;
}
template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
    return a + b + c - max({a, b, c}) - min({a, b, c});
}
template <class T> void Sort(T &a, T &b, bool rev = false) { 
    if (rev == false) if (a > b) swap(a, b);
    else if (b > a) swap(b, a);
}
template <typename T, typename... Args>
void Sort(T& a, T& b, T& c, Args&... args) {
    vector<T> vec = {a, b, c, args...};
    sort(vec.begin(), vec.end());
    auto it = vec.begin();
    a = *it++; b = *it++; c = *it++;
    int dummy[] = { (args = *it++, 0)... };
    static_cast<void>(dummy);
}
 
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
 
class Compress {
public:
    int sz = 0;
    // gp_hash_table<int, int, custom_hash> Z, UZ;
    unordered_map<int, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, int> UZ;   // 圧縮した値 -> 元の値
 
    Compress(const vector<int> &V, int base = 0) {
        this->sz = base;
        set<int> s(V.begin(), V.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<int> &V1, const vector<int> &V2, int base = 0) {
        this->sz = base;
        vector<int> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<int> s(V3.begin(), V3.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2, const vector<int> &V3, int base = 0) {
        this->sz = base;
        vector<int> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<int> s(V4.begin(), V4.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2,
            const vector<int> &V3, const vector<int> &V4, int base = 0) {
        this->sz = base;
        vector<int> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<int> s(V5.begin(), V5.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[ret[i]];
        }
        return ret;
    }
 
    vector<int> unzip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[ret[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    int encode(int x) { return Z[x]; }
    int decode(int x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};
 
template<typename T> struct BIT {
    int N;             // 要素数
    vector<T> bit[2];  // データの格納先
    BIT(int N_, int x = 0) {
        N = N_ + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0) {
            for (int i = 0; i < N; i++) add(i, x);
        }
    }
    BIT(const vector<int> &A) {
        N = A.size() + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = 0;
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};
 
template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }
 
    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }
    
    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
};
 
using mint = Modint<MOD>;
 
istream &operator >>(istream &is, mint& x) {
    int t; is >> t; x = t; return (is);
}
ostream &operator <<(ostream &os, const mint& x) {
    return os << x.val;
}
mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}
 
int modpow(__int128_t x, int n, int mod) {
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
int modinv(__int128_t x, int mod) {
    assert(mod > 0);
    // assert(x > 0);
    if (x == 1 or x == 0) return 1;
    return mod - modinv(mod % x, mod) * (mod / x) % mod;
}
 
istream &operator >>(istream &is, __int128_t& x) {
    string S; is >> S;
    __int128_t ret = 0;
    int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9')
            ret = ret * 10 + S[i] - '0';
    x = ret * f;
    return (is);
}
ostream &operator <<(ostream &os, __int128_t x) {
    ostream::sentry s(os);
    if (s) {
        __uint128_t tmp = x < 0 ? -x : x;
        char buffer[128]; char *d = end(buffer);
        do {
            --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
        } while (tmp != 0);
        if (x < 0) { --d; *d = '-'; }
        int len = end(buffer) - d;
        if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
    }
    return os;
}
 
__int128_t stoll(string &S) {
    __int128_t ret = 0; int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
    return ret * f;
}
__int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
__int128_t lcm(__int128_t a, __int128_t b) {
    return a / gcd(a, b) * b;
    // lcmが__int128_tに収まる必要あり
}
 
string to_string(ld x, int k) { // xの小数第k位までをstring化する
    assert(k >= 0);
    stringstream ss;
    ss << setprecision(k + 2) << x;
    string s = ss.str();
    if (s.find('.') == string::npos) s += '.';
    int pos = s.find('.');
    for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
    s.pop_back();
    if (s.back() == '.') s.pop_back();
    return s;
 
    // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
    // ss << setprecision(k + 1) << x;
    // string s = ss.str();
    // if (s.find('.') == string::npos) s += '.';
    // int pos = s.find('.');
    // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
    // if (s.back() == '.') s.pop_back();
    // return s;
}
string to_string(__int128_t x) {
    string ret = "";
    if (x < 0) { ret += "-"; x *= -1; }
    while (x) { ret += (char)('0' + x % 10); x /= 10; }
    reverse(ret.begin(), ret.end());
    return ret;
}
string to_string(char c) { string s = ""; s += c; return s; }
 
template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};
 
vector<mint> _fac, _finv, _inv;
void COMinit(int N) {
    _fac.resize(N + 1); _finv.resize(N + 1);  _inv.resize(N + 1);
    _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
    for (int i = 2; i <= N; i++) {
        _fac[i] = _fac[i-1] * mint(i);
        _inv[i] = -_inv[MOD % i] * mint(MOD / i);
        _finv[i] = _finv[i - 1] * _inv[i];
    }
}
 
mint FAC(int N) {
    if (N < 0) return 0; return _fac[N];
}
mint COM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] * _finv[K] * _finv[N - K];
}
mint PERM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] *  _finv[N - K];
}
mint NHK(int N, int K) { // initのサイズに注意
    if (N == 0 && K == 0)  return 1;
    return COM(N + K - 1, K);
}
 
#pragma endregion

int H, W;
bool isvalid(int x, int y) {
    if (x >= 0 && x < H && y >= 0 && y < W) return true;
    else return false;
}

signed main() {
    while (cin >> W >> H, H) {
        int sx, sy;
        vector<pair<int, int>> C; // 飴のあるマスの集合
        vector<vector<char>> S(H, vector<char>(W));
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                cin >> S[i][j];
                if (S[i][j] == 'o') sx = i, sy = j;
                if (S[i][j] == '*') {
                    C.pb(i, j);
                }
            }
        }

        vector<vector<Edge>> G(H * W);
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (S[i][j] == 'x') continue;

                for (int k = 0; k < 4; k++) {
                    int ni = i + dx[k];
                    int nj = j + dy[k];

                    if (!isvalid(ni, nj)) continue;
                    if (S[ni][nj] == 'x') continue;

                    int c = 1;

                    G[i*W + j].pb(ni*W + nj, c);
                }
            }
        }

        int szC = C.size();
        vector<int> V(szC + 1); // 飴 + 始点
        V[0] = sx*W + sy;
        for (int i = 1; i <= szC; i++) {
            V[i] = C[i - 1].first*W + C[i - 1].second;
        }

        vector<vector<int>> dist(szC + 1, vector<int>(szC + 1, INFL));
        // 頂点V[i]から頂点V[j]への距離表
        for (int i = 0; i < szC + 1; i++) {
            vector<int> D(H * W, INFL);
            D[V[i]] = 0;
            
            std::priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
            pq.emplace(0, V[i]);
            
            while (pq.size()) {
                int d = pq.top().first;
                int v = pq.top().second;
                pq.pop();
                
                if (d > D[v]) continue;
                for (auto &e : G[v]) {
                    if (D[e.to] > D[v] + e.cost) {
                        D[e.to] = D[v] + e.cost;
                        pq.emplace(D[e.to], e.to);
                    }
                }
            }

            for (int j = 0; j < szC + 1; j++) {
                dist[i][j] = D[V[j]];
            }
        }

        // for (int i = 0; i < szC + 1; i++) {
        //     for (int j = 0; j < szC + 1; j++) {
        //         cout << dist[i][j] << (j != szC + 1 - 1 ? " " : "\n");
        //     }
        // }
        
        vector<vector<int>> dp(1LL << (szC + 1), vector<int>(szC + 1, INFL));
        dp[1 << 0][0] = 0;

        for (int i = 0; i < (1LL << (szC + 1)); i++) { // 全ての集合(状態)を小さい順に見る
            // if (!(i & (1 << 0))) continue; // 始点を含んでいないならとばす
            for (int j = 0; j < (szC + 1); j++) { // 移動元としてあり得る都市を探し、
                if (dp[i][j] == INFL) continue;
                // if (!(i & (1 << j))) continue;

                for (int k = 0; k < (szC + 1); k++) { // 移動先の都市を探す
                    if (i & (1LL << k)) continue; // 集合iに都市kが含まれてるならとばす

                    int d = dist[j][k];
                    dp[i + (1LL << k)][k] = min(dp[i + (1LL << k)][k], dp[i][j] + d);
                }
            }
        }

        // 訪問した都市の集合が111...1で、最後に訪れた都市がgであるとき
        int ans = *min_element(dp[(1 << (szC + 1)) - 1].begin(), dp[(1 << (szC + 1)) - 1].end());
        if (ans == INFL) cout << -1 << endl;
        else cout << ans << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3624
final_rank: 11

code_snippet: #pragma region Macros
 
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,fma,abm,mmx,avx,avx2,popcnt")
 
#include <bits/extc++.h>
// #include <atcoder/all>
// using namespace atcoder;
using namespace std;
using namespace __gnu_pbds;
 
// #include <boost/multiprecision/cpp_dec_float.hpp>
// #include <boost/multiprecision/cpp_int.hpp>
// namespace mp = boost::multiprecision;
// using Bint = mp::cpp_int;
// using Bdouble = mp::number<mp::cpp_dec_float<256>>;
// Bdouble Beps = 0.00000000000000000000000000000001; // 1e-32
// const bool equals(Bdouble a, Bdouble b) { return mp::fabs(a - b) < Beps; }
 
#define pb emplace_back
#define int ll
#define endl '\n'
// #define unordered_map<int, int> gp_hash_table<int, int, custom_hash> 
 
#define sqrt __builtin_sqrtl
#define cbrt __builtin_cbrtl
#define hypot __builtin_hypotl
 
#define next asdnext
#define prev asdprev
 
using ll = long long;
using ld = long double;
const ld PI = acosl(-1);
const int INF = 1 << 30;
const ll INFL = 1LL << 61;
// const int MOD = 998244353;
const int MOD = 1000000007;
 
const ld EPS = 1e-10;
const bool equals(ld a, ld b) { return fabs((a) - (b)) < EPS; }
 
const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}; // → ↓ ← ↑ ↘ ↙ ↖ ↗
const vector<int> dy = {1, 0, -1, 0, 1, -1, -1, 1};
 
#define EC int
struct Edge {
    int from, to;
    EC cost;
    Edge() : from(-1), to(-1), cost(-1) {}
    Edge(int to, EC cost) : to(to), cost(cost) {}
    Edge(int from, int to, EC cost) : from(from), to(to), cost(cost) {}
    bool operator ==(const Edge& e) {
        return this->from == e.from && this->to == e.to && this->cost == e.cost;
    }
    bool operator !=(const Edge& e) {
        return this->from != e.from or this->to != e.to or this->cost != e.cost;
    }
    bool operator <(const Edge& e) { return this->cost < e.cost; }
    bool operator >(const Edge& e) { return this->cost > e.cost; }
};
 
chrono::system_clock::time_point start;
__attribute__((constructor))
void constructor() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    start = chrono::system_clock::now();
}
 
random_device seed_gen;
mt19937_64 rng(seed_gen());
uniform_int_distribution<int> dist_x(0, 1e9);
struct RNG {
    unsigned Int(unsigned l, unsigned r) {
        return dist_x(rng) % (r - l + 1) + l;
    }
    ld Double() {
        return ld(dist_x(rng)) / 1e9;
    }
} rnd;
 
using i64 = ll;
// using i64 = uint64_t;
// bit演算, x==0の場合は例外処理した方がよさそう. 区間は [l, r)
i64 lrmask(int l, int r) { return (1LL << r) - (1LL << l); }
i64 sub_bit(i64 x, int l, int r) { i64 b = x & ((1LL << r) - (1LL << l)); return b >> l; } // r溢れ可
i64 bit_width(i64 x) { return 64 - __builtin_clzll(x) + (x == 0); }
 
i64 popcount(i64 x) { return __builtin_popcountll(x); }
i64 popcount(i64 x, int l, int r) { return __builtin_popcountll(sub_bit(x, l, r)); }
i64 unpopcount(i64 x) { return bit_width(x) - __builtin_popcountll(x); }
i64 unpopcount(i64 x, int l, int r) { return r - l - __builtin_popcountll(sub_bit(x, l, r)); }
bool is_pow2(i64 x) { return __builtin_popcountll(x) == 1; } // xが負のときは常にfalse
bool is_pow4(i64 x) { return __builtin_popcount(x) == 1 && __builtin_ctz(x) % 2 == 0; }
 
int top_bit(i64 x) { return 63 - __builtin_clzll(x);} // 2^kの位 (x > 0)
int bot_bit(i64 x) { return __builtin_ctzll(x);} // 2^kの位 (x > 0)
int next_bit(i64 x, int k) { // upper_bound
    x >>= (k + 1);
    int pos = k + 1;
    while (x > 0) {
        if (x & 1) return pos;
        x >>= 1;
        pos++;
    }
    return -1;
}
int prev_bit(i64 x, int k) {
    // k = min(k, bit_width(x)); ?
    int pos = 0;
    while (x > 0 && pos < k) {
        if (x & 1) {
            if (pos < k) return pos;
        }
        x >>= 1;
        pos++;
    }
    return -1;
}
int kth_bit(i64 x, int k) { // kは1-indexed
    int pos = 0, cnt = 0;
    while (x > 0) {
        if (x & 1) {
            cnt++;
            if (cnt == k) return pos;
        }
        x >>= 1;
        pos++;
    }
    return -1;
}
i64 MSB(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // mask
i64 LSB(i64 x) { return (x & -x); } // mask
 
int countl_zero(i64 x) { return __builtin_clzll(x); }
int countl_one(i64 x) {
    i64 ret = 0, k = 63 - __builtin_clzll(x);
    while (k != -1 && (x & (1LL << k))) { k--; ret++; }
    return ret;
}
int countr_zero(i64 x) { return __builtin_ctzll(x); } // x==0のとき64が返ることに注意
int countr_one(i64 x) { int ret = 0; while (x & 1) { x >>= 1; ret++; } return ret; }
 
int floor_log2(i64 x) { if (x == 0) return 0; return 63 - __builtin_clzll(x); } // top_bit
int ceil_log2(i64 x) { if (x == 0) return 0; return 64 - __builtin_clzll(x - 1); }
i64 bit_floor(i64 x) { if (x == 0) return 0; return 1LL << (63 - __builtin_clzll(x)); } // MSB
i64 bit_ceil(i64 x) { if (x == 0) return 0; return 1LL << (64 - __builtin_clzll(x - 1)); }
 
i64 rotl(i64 x, int k) { // 有効bit内でrotate. オーバーフロー注意
    i64 w = bit_width(x); k %= w;
    return ((x << k) | (x >> (w - k))) & ((1LL << w) - 1);
}
// i64 rotl(i64 x, i64 l, i64 m, i64 r) {}
i64 rotr(i64 x, int k) {
    i64 w = bit_width(x); k %= w;
    return ((x >> k) | (x << (w - k))) & ((1LL << w) - 1);
}
// i64 rotr(i64 x, i64 l, i64 m, i64 r) {}
i64 bit_reverse(i64 x) { // 有効bit内で左右反転
    i64 r = 0, w = bit_width(x);
    for (i64 i = 0; i < w; i++) r |= ((x >> i) & 1) << (w - i - 1);
    return r;
}
// i64 bit_reverse(i64 x, int l, int r) { return 0; }
 
bool is_palindrome(i64 x) { return x == bit_reverse(x); }
bool is_palindrome(i64 x, int l, int r) { i64 b = sub_bit(x, l, r); return b == bit_reverse(b); }
i64 concat(i64 a, i64 b) { return (a << bit_width(b)) | b; } // オーバーフロー注意
i64 erase(i64 x, int l, int r) { return x >> r << l | x & ((1LL << l) - 1); } // [l, r) をカット
 
i64 hamming(i64 a, i64 b) { return __builtin_popcountll(a ^ b); }
i64 hamming(i64 a, i64 b, int l, int r) { return __builtin_popcountll(sub_bit(a, l, r) ^ sub_bit(b, l, r)); }
i64 compcount(i64 x) { return (__builtin_popcountll(x ^ (x >> 1)) + (x & 1)) / 2; }
i64 compcount2(i64 x) { return compcount(x & (x >> 1)); } // 長さ2以上の連結成分の個数
i64 adjacount(i64 x) { return __builtin_popcountll(x & (x >> 1)); } // 隣接する1のペアの個数
 
i64 next_combination(i64 x) {
    i64 t = x | (x - 1); return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctzll(x) + 1));
}
 
 
__int128_t POW(__int128_t x, int n) {
    __int128_t ret = 1;
    assert(n >= 0);
    if (x == 1 or n == 0) ret = 1;
    else if (x == -1 && n % 2 == 0) ret = 1; 
    else if (x == -1) ret = -1; 
    else if (n % 2 == 0) {
        assert(x < INFL);
        ret = POW(x * x, n / 2);
    } else {
        assert(x < INFL);
        ret = x * POW(x, n - 1);
    }
    return ret;
}
int per(int x, int y) { // x = qy + r (0 <= r < y) を満たすq
    assert(y != 0);
    if (x >= 0 && y > 0) return x / y;
    if (x >= 0 && y < 0) return x / y - (x % y < 0);
    if (x < 0 && y < 0) return x / y + (x % y < 0);
    return x / y - (x % y < 0); //  (x < 0 && y > 0) 
}
int mod(int x, int y) { // x = qy + r (0 <= r < y) を満たすr
    assert(y != 0);
    if (x >= 0) return x % y;
    __int128_t ret = x % y; // (x < 0)
    ret += (__int128_t)abs(y) * INFL;
    ret %= abs(y);
    return ret;
}
int floor(int x, int y) { // (ld)x / y 以下の最大の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x >= 0 ? x / y : (x + 1) / y - 1;
}
int ceil(int x, int y) { // (ld)x / y 以上の最小の整数
    assert(y != 0);
    if (y < 0) x = -x, y = -y;
    return x > 0 ? (x - 1) / y + 1 : x / y;
}
int round(int x, int y) { // (ld)(x/y)を小数点第1位について四捨五入
    assert(y != 0);
    return (x * 2 + y) / (y * 2);
}
int round(int x, int y, int k) { // (ld)(x/y)を10^kの位に関して四捨五入
    assert(y != 0 && k >= 0);
    if (k == 0) return (x * 2 + y) / (y * 2);
    x /= y * POW(10, k - 1);
    if (x % 10 >= 5) return (x + 10 - x % 10) * POW(10, k - 1);
    return x * POW(10, k - 1);
}
int round2(int x, int y) { // 五捨五超入 // 未verify
    assert(y != 0);
    if (y < 0) y = -y, x = -x;
    int z = x / y;
    if ((z * 2 + 1) * y <= y * 2) z++;
    return z;
}
ld round(ld x, int k) { // xを10^kの位に関して四捨五入. to_string(x, k)優先
    // x += EPS;
    ld d = pow(10, -k);
    return round(x * d) / d;
}
ld floor(ld x, int k) { // xを10^kの位に関してflooring
    // x += EPS;
    ld d = pow(10, -k);
    return floor(x * d) / d; // 未verify
}
ld ceil(ld x, int k) { // xを10^kの位に関してceiling
    // x -= EPS;
    ld d = pow(10, -k);
    return ceil(x * d) / d; // 未verify
}
// int kth(int x, int y, int k) { // x / yの10^kの位の桁
// }
int floor(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return floor(x / y);
    // floor(x) = ceil(x - 1) という話も
}
int ceil(ld x, ld y) { // 誤差対策TODO // ceil(p/q) = -floor(-(p/q))らしい
    assert(!equals(y, 0));
    return ceil(x / y);
    // ceil(x) = floor(x + 1)
}
int perl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす q
    // 未verify. 誤差対策TODO. EPS外してもいいかも。
    assert(!equals(y, 0));
    if (x >= 0 && y > 0) return floor(x / y)+EPS;
    if (x >= 0 && y < 0) return -floor(x / fabs(y));
    if (x < 0 && y < 0) return floor(x / y) + (x - floor(x/y)*y < -EPS);
    return floor(x / y) - (x - floor(x/y)*y < -EPS); //  (x < 0 && y > 0) 
}
ld modl(ld x, ld y) { // x = qy + r (0 <= r < y, qは整数) を満たす r
    // 未verify. 誤差対策TODO. -0.0が返りうる。
    assert(!equals(y, 0));
    if (x >= 0) return x - fabs(y)*fabs(per(x, y));
    return x - fabs(y)*floor(x, fabs(y));
}
int seisuu(ld x) { return (int)x; } // 整数部分. 誤差対策TODO
int modf(ld x) {
	if (x < 0) return ceill(x);
	else return floorl(x);
}
// 正なら+EPS, 負なら-EPSしてから、文字列に直して小数点以下を捨てる?
int seisuu(int x, int y) {
    assert(y != 0);
    return x / y;
}
int seisuu(ld x, ld y) { // 誤差対策TODO
    assert(!equals(y, 0));
    return (int)(x / y);
}
 
template <class T> pair<T, T> max(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first > b.first or a.first == b.first && a.second > b.second) return a;
    return b;
}
template <class T> pair<T, T> min(const pair<T, T> &a, const pair<T, T> &b) {
    if (a.first < b.first or a.first == b.first && a.second < b.second) return a;
    return b;
}
 
template <class T> bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; } return false;
}
template <class T> bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; } return false;
}
template <class T> T mid(T a, T b, T c) { // 誤差対策TODO
    return a + b + c - max({a, b, c}) - min({a, b, c});
}
template <class T> void Sort(T &a, T &b, bool rev = false) { 
    if (rev == false) if (a > b) swap(a, b);
    else if (b > a) swap(b, a);
}
template <typename T, typename... Args>
void Sort(T& a, T& b, T& c, Args&... args) {
    vector<T> vec = {a, b, c, args...};
    sort(vec.begin(), vec.end());
    auto it = vec.begin();
    a = *it++; b = *it++; c = *it++;
    int dummy[] = { (args = *it++, 0)... };
    static_cast<void>(dummy);
}
 
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
 
class Compress {
public:
    int sz = 0;
    // gp_hash_table<int, int, custom_hash> Z, UZ;
    unordered_map<int, int> Z;    // 元の値 -> 圧縮した値
    unordered_map<int, int> UZ;   // 圧縮した値 -> 元の値
 
    Compress(const vector<int> &V, int base = 0) {
        this->sz = base;
        set<int> s(V.begin(), V.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
    
    Compress(const vector<int> &V1, const vector<int> &V2, int base = 0) {
        this->sz = base;
        vector<int> V3 = V2;
        V3.insert(V3.end(), V1.begin(), V1.end());
        set<int> s(V3.begin(), V3.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2, const vector<int> &V3, int base = 0) {
        this->sz = base;
        vector<int> V4 = V1;
        V4.insert(V4.end(), V2.begin(), V2.end());
        V4.insert(V4.end(), V3.begin(), V3.end());
        set<int> s(V4.begin(), V4.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    Compress(const vector<int> &V1, const vector<int> &V2,
            const vector<int> &V3, const vector<int> &V4, int base = 0) {
        this->sz = base;
        vector<int> V5 = V1;
        V5.insert(V5.end(), V2.begin(), V2.end());
        V5.insert(V5.end(), V3.begin(), V3.end());
        V5.insert(V5.end(), V4.begin(), V4.end());
        set<int> s(V5.begin(), V5.end());
 
        for (int x : s) {
            this->Z[x] = this->sz;
            this->UZ[this->sz] = x;
            this->sz++;
        }
    }
 
    vector<int> zip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = Z[ret[i]];
        }
        return ret;
    }
 
    vector<int> unzip(const vector<int> &V) {
        vector<int> ret = V;
        for (int i = 0; i < (int)V.size(); i++) {
            ret[i] = UZ[ret[i]];
        }
        return ret;
    }
 
    int size() { return sz; }
 
    int encode(int x) { return Z[x]; }
    int decode(int x) {
        if (UZ.find(x) == UZ.end()) return -1; // xが元の配列に存在しないとき
        return UZ[x];
    }
};
 
class UnionFind {
public:
	UnionFind() = default;
    UnionFind(int N) : par(N), sz(N, 1) {
        iota(par.begin(), par.end(), 0);
    }
	int root(int x) {
		if (par[x] == x) return x;
		return (par[x] = root(par[x]));
	}
	bool unite(int x, int y) {
		int rx = root(x);
		int ry = root(y);
        if (rx == ry) return false;
		if (sz[rx] < sz[ry]) swap(rx, ry);
		sz[rx] += sz[ry];
		par[ry] = rx;
        return true;
	}
	bool issame(int x, int y) { return (root(x) == root(y)); }
	int size(int x) { return sz[root(x)]; }
    vector<vector<int>> groups(int N) {
        vector<vector<int>> G(N);
        for (int x = 0; x < N; x++) {
            G[root(x)].push_back(x);
        }
		G.erase( remove_if(G.begin(), G.end(),
            [&](const vector<int>& V) { return V.empty(); }), G.end());
        return G;
    }
private:
	vector<int> par, sz;
};
 
template<typename T> struct BIT {
    int N;             // 要素数
    vector<T> bit[2];  // データの格納先
    BIT(int N_, int x = 0) {
        N = N_ + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        if (x != 0) {
            for (int i = 0; i < N; i++) add(i, x);
        }
    }
    BIT(const vector<int> &A) {
        N = A.size() + 1;
        bit[0].assign(N, 0); bit[1].assign(N, 0);
        for (int i = 0; i < (int)A.size(); i++) add(i, A[i]);
    }
    void add_sub(int p, int i, T x) {
        while (i < N) { bit[p][i] += x; i += (i & -i); }
    }
    void add(int l, int r, T x) {
        add_sub(0, l + 1, -x * l); add_sub(0, r + 1, x * r);
        add_sub(1, l + 1, x); add_sub(1, r + 1, -x);
    }
    void add(int i, T x) { add(i, i + 1, x); }
    T sum_sub(int p, int i) {
        T ret = 0;
        while (i > 0) { ret += bit[p][i]; i -= (i & -i); }
        return ret;
    }
    T sum(int i) { return sum_sub(0, i) + sum_sub(1, i) * i; }
    T sum(int l, int r) { return sum(r) - sum(l); }
    T get(int i) { return sum(i, i + 1); }
    void set(int i, T x) { T s = get(i); add(i, -s + x); }
};
 
template<int mod> class Modint {
public:
    int val = 0;
    Modint(int x = 0) { while (x < 0) x += mod; val = x % mod; }
    Modint(const Modint &r) { val = r.val; }
 
    Modint operator -() { return Modint(-val); } // 単項
    Modint operator +(const Modint &r) { return Modint(*this) += r; }
    Modint operator +(const int &q) { Modint r(q); return Modint(*this) += r; }
    Modint operator -(const Modint &r) { return Modint(*this) -= r; }
    Modint operator -(const int &q) { Modint r(q); return Modint(*this) -= r; }
    Modint operator *(const Modint &r) { return Modint(*this) *= r; }
    Modint operator *(const int &q) { Modint r(q); return Modint(*this) *= r; }
    Modint operator /(const Modint &r) { return Modint(*this) /= r; }
    Modint operator /(const int &q) { Modint r(q); return Modint(*this) /= r; }
    
    Modint& operator ++() { val++; if (val >= mod) val -= mod; return *this; } // 前置
    Modint operator ++(signed) { ++*this; return *this; } // 後置
    Modint& operator --() { val--; if (val < 0) val += mod; return *this; }
    Modint operator --(signed) { --*this; return *this; }
    Modint &operator +=(const Modint &r) { val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator +=(const int &q) { Modint r(q); val += r.val; if (val >= mod) val -= mod; return *this; }
    Modint &operator -=(const Modint &r) { if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator -=(const int &q) { Modint r(q);  if (val < r.val) val += mod; val -= r.val; return *this; }
    Modint &operator *=(const Modint &r) { val = val * r.val % mod; return *this; }
    Modint &operator *=(const int &q) { Modint r(q); val = val * r.val % mod; return *this; }
    Modint &operator /=(const Modint &r) {
        int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    Modint &operator /=(const int &q) {
        Modint r(q); int a = r.val, b = mod, u = 1, v = 0;
        while (b) {int t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v);}
        val = val * u % mod; if (val < 0) val += mod;
        return *this;
    }
    bool operator ==(const Modint& r) { return this -> val == r.val; }
    bool operator <(const Modint& r) { return this -> val < r.val; }
    bool operator >(const Modint& r) { return this -> val > r.val; }
    bool operator !=(const Modint& r) { return this -> val != r.val; }
};
 
using mint = Modint<MOD>;
 
istream &operator >>(istream &is, mint& x) {
    int t; is >> t; x = t; return (is);
}
ostream &operator <<(ostream &os, const mint& x) {
    return os << x.val;
}
mint modpow(const mint &x, int n) {
    if (n < 0) return (mint)1 / modpow(x, -n); // 未verify
    assert(n >= 0);
    if (n == 0) return 1;
    mint t = modpow(x, n / 2);
    t = t * t;
    if (n & 1) t = t * x;
    return t;
}
 
int modpow(__int128_t x, int n, int mod) {
    assert(n >= 0 && mod > 0); // TODO: n <= -1
    __int128_t ret = 1;
    while (n > 0) {
        if (n % 2 == 1) ret = ret * x % mod;
        x = x * x % mod;
        n /= 2;
    }
    return ret;
}
int modinv(__int128_t x, int mod) {
    assert(mod > 0);
    // assert(x > 0);
    if (x == 1 or x == 0) return 1;
    return mod - modinv(mod % x, mod) * (mod / x) % mod;
}
 
istream &operator >>(istream &is, __int128_t& x) {
    string S; is >> S;
    __int128_t ret = 0;
    int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9')
            ret = ret * 10 + S[i] - '0';
    x = ret * f;
    return (is);
}
ostream &operator <<(ostream &os, __int128_t x) {
    ostream::sentry s(os);
    if (s) {
        __uint128_t tmp = x < 0 ? -x : x;
        char buffer[128]; char *d = end(buffer);
        do {
            --d; *d = "0123456789"[tmp % 10]; tmp /= 10;
        } while (tmp != 0);
        if (x < 0) { --d; *d = '-'; }
        int len = end(buffer) - d;
        if (os.rdbuf()->sputn(d, len) != len) os.setstate(ios_base::badbit);
    }
    return os;
}
 
__int128_t stoll(string &S) {
    __int128_t ret = 0; int f = 1;
    if (S[0] == '-') f = -1; 
    for (int i = 0; i < S.length(); i++)
        if ('0' <= S[i] && S[i] <= '9') ret = ret * 10 + S[i] - '0';
    return ret * f;
}
__int128_t gcd(__int128_t a, __int128_t b) { return b ? gcd(b, a % b) : a; }
__int128_t lcm(__int128_t a, __int128_t b) {
    return a / gcd(a, b) * b;
    // lcmが__int128_tに収まる必要あり
}
 
string to_string(ld x, int k) { // xの小数第k位までをstring化する
    assert(k >= 0);
    stringstream ss;
    ss << setprecision(k + 2) << x;
    string s = ss.str();
    if (s.find('.') == string::npos) s += '.';
    int pos = s.find('.');
    for (int i = 0; k >= (int)s.size() - 1 - pos; i++) s += '0';
    s.pop_back();
    if (s.back() == '.') s.pop_back();
    return s;
 
    // stringstream ss; // 第k+1位を四捨五入して第k位まで返す
    // ss << setprecision(k + 1) << x;
    // string s = ss.str();
    // if (s.find('.') == string::npos) s += '.';
    // int pos = s.find('.');
    // for (int i = 0; k > (int)s.size() - 1 - pos; i++) s += '0';
    // if (s.back() == '.') s.pop_back();
    // return s;
}
string to_string(__int128_t x) {
    string ret = "";
    if (x < 0) { ret += "-"; x *= -1; }
    while (x) { ret += (char)('0' + x % 10); x /= 10; }
    reverse(ret.begin(), ret.end());
    return ret;
}
string to_string(char c) { string s = ""; s += c; return s; }
 
template<class T> size_t HashCombine(const size_t seed,const T &v) {
    return seed^(hash<T>()(v)+0x9e3779b9+(seed<<6)+(seed>>2));
}
template<class T,class S> struct hash<pair<T,S>>{
    size_t operator()(const pair<T,S> &keyval) const noexcept {
        return HashCombine(hash<T>()(keyval.first), keyval.second);
    }
};
template<class T> struct hash<vector<T>>{
    size_t operator()(const vector<T> &keyval) const noexcept {
        size_t s=0;
        for (auto&& v: keyval) s=HashCombine(s,v);
        return s;
    }
};
template<int N> struct HashTupleCore{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{
        size_t s=HashTupleCore<N-1>()(keyval);
        return HashCombine(s,get<N-1>(keyval));
    }
};
template <> struct HashTupleCore<0>{
    template<class Tuple> size_t operator()(const Tuple &keyval) const noexcept{ return 0; }
};
template<class... Args> struct hash<tuple<Args...>>{
    size_t operator()(const tuple<Args...> &keyval) const noexcept {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};
 
vector<mint> _fac, _finv, _inv;
void COMinit(int N) {
    _fac.resize(N + 1); _finv.resize(N + 1);  _inv.resize(N + 1);
    _fac[0] = _fac[1] = 1; _finv[0] = _finv[1] = 1; _inv[1] = 1;
    for (int i = 2; i <= N; i++) {
        _fac[i] = _fac[i-1] * mint(i);
        _inv[i] = -_inv[MOD % i] * mint(MOD / i);
        _finv[i] = _finv[i - 1] * _inv[i];
    }
}
 
mint FAC(int N) {
    if (N < 0) return 0; return _fac[N];
}
mint COM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] * _finv[K] * _finv[N - K];
}
mint PERM(int N, int K) {
    if (N < K) return 0; if (N < 0 or K < 0) return 0;
    return _fac[N] *  _finv[N - K];
}
mint NHK(int N, int K) { // initのサイズに注意
    if (N == 0 && K == 0)  return 1;
    return COM(N + K - 1, K);
}
 
#pragma endregion

int H, W;
bool isvalid(int x, int y) {
    if (x >= 0 && x < H && y >= 0 && y < W) return true;
    else return false;
}

signed main() {
    while (cin >> W >> H, H) {
        int sx, sy;
        vector<pair<int, int>> C; // 飴のあるマスの集合
        vector<vector<char>> S(H, vector<char>(W));
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                cin >> S[i][j];
                if (S[i][j] == 'o') sx = i, sy = j;
                if (S[i][j] == '*') {
                    C.pb(i, j);
                }
            }
        }

        vector<vector<Edge>> G(H * W);
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                if (S[i][j] == 'x') continue;

                for (int k = 0; k < 4; k++) {
                    int ni = i + dx[k];
                    int nj = j + dy[k];

                    if (!isvalid(ni, nj)) continue;
                    if (S[ni][nj] == 'x') continue;

                    int c = 1;

                    G[i*W + j].pb(ni*W + nj, c);
                }
            }
        }

        int szC = C.size();
        vector<int> V(szC + 1); // 飴 + 始点
        V[0] = sx*W + sy;
        for (int i = 1; i <= szC; i++) {
            V[i] = C[i - 1].first*W + C[i - 1].second;
        }

        vector<vector<int>> dist(szC + 1, vector<int>(szC + 1, INFL));
        // 頂点V[i]から頂点V[j]への距離表
        for (int i = 0; i < szC + 1; i++) {
            vector<int> D(H * W, INFL);
            D[V[i]] = 0;
            
            std::priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
            pq.emplace(0, V[i]);
            
            while (pq.size()) {
                int d = pq.top().first;
                int v = pq.top().second;
                pq.pop();
                
                if (d > D[v]) continue;
                for (auto &e : G[v]) {
                    if (D[e.to] > D[v] + e.cost) {
                        D[e.to] = D[v] + e.cost;
                        pq.emplace(D[e.to], e.to);
                    }
                }
            }

            for (int j = 0; j < szC + 1; j++) {
                dist[i][j] = D[V[j]];
            }
        }

        // for (int i = 0; i < szC + 1; i++) {
        //     for (int j = 0; j < szC + 1; j++) {
        //         cout << dist[i][j] << (j != szC + 1 - 1 ? " " : "\n");
        //     }
        // }
        
        vector<vector<int>> dp(1LL << (szC + 1), vector<int>(szC + 1, INFL));
        dp[0][0] = 0;

        for (int i = 0; i < (1LL << (szC + 1)); i++) { // 全ての集合(状態)を小さい順に見る
            // if (!(i & (1 << 0))) continue; // 始点を含んでいないならとばす
            for (int j = 0; j < (szC + 1); j++) { // 移動元としてあり得る都市を探し、
                if (dp[i][j] == INFL) continue;
                // if (!(i & (1 << j))) continue;

                for (int k = 0; k < (szC + 1); k++) { // 移動先の都市を探す
                    if (i & (1LL << k)) continue; // 集合iに都市kが含まれてるならとばす

                    int d = dist[j][k];
                    dp[i + (1LL << k)][k] = min(dp[i + (1LL << k)][k], dp[i][j] + d);
                }
            }
        }

        // 訪問した都市の集合が111...1で、最後に訪れた都市がgであるとき
        int ans = *min_element(dp[(1 << (szC + 1)) - 1].begin(), dp[(1 << (szC + 1)) - 1].end());
        if (ans == INFL) cout << -1 << endl;
        else cout << ans << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3580
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define rrep(i,start,end) for (long long i = start;i >= (long long)(end);i--)
#define repn(i,end) for(long long i = 0; i <= (long long)(end); i++)
#define reps(i,start,end) for(long long i = start; i < (long long)(end); i++)
#define repsn(i,start,end) for(long long i = start; i <= (long long)(end); i++)
#define each(p,a) for(auto &p:a)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<long long> vll;
typedef vector<pair<long long ,long long>> vpll;
typedef vector<vector<long long>> vvll;
typedef set<ll> sll;
typedef map<long long , long long> mpll;
typedef pair<long long ,long long> pll;
typedef tuple<long long , long long , long long> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (int)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
inline ll lfloor(ll x,ll m){return (x - ((x % m+ m)%m))/m;}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

// for AOJ or ICPC or etc..
// 全部が0だったらtrueを返す
template<class Tp> bool zero (const Tp &x) {return x == 0;}
template<class Tp, class... Args> bool zero (const Tp &x, const Args& ...args) {return zero(x) and zero(args...);}


int warshall_floyd(vector<vector<ll>> &dist){
  int size = (int)dist.size();
  rep(k,size){
    rep(i,size){
      rep(j,size){
        if(i == j){
          chmin(dist[i][j],0LL);
        }
        if(dist[i][k] != INF && dist[k][j] != INF){
          chmin(dist[i][j],dist[i][k] + dist[k][j]);
        }
      }
    }
  }
  //負の閉路判定あれば−1大丈夫なら1
  rep(i,size){
    if(dist[i][i]<0){
      return -1;
    }
  }
  return 1;
}
// 変数をちゃんと全部受け取る！
void solve(ll w,ll h){
  vector<string> g(h);
  rep(i,h){
    cin >> g[i];
  }
  ll s = 0;
  vll plc;
  auto clc = [&](ll y, ll x){
    return y * w + x;
  };
  auto rclc = [&](ll v)->pll{
    return {v/w,v % w};
  };
  vvll dist(h * w,vll(h * w,INF));
  rep(i,h){
    rep(j,w){
      // cout <<i << " " << j << endl;
      if(g[i][j] == 'x'){
        continue;
      }else if(g[i][j] == 'o'){
        s = clc(i,j);
      }else if(g[i][j] == '*'){
        plc.push_back(clc(i,j));
      } 
      rep(k,4){
        ll ny = i + _ta[k];
        ll nx = j + _yo[k];
        if(isin(ny,nx,h,w) && g[ny][nx] != 'X'){
          dist[clc(i,j)][clc(ny,nx)] = 1;
          // dist[clc(ny,nx)][clc(i,j)] = 1;
        }
      }
    }
  }
  // cout << "here" << endl;
  warshall_floyd(dist);
  // rep(i,h * w){
  //   rep(j,h * w){
  //     cout << ((dist[i][j] == INF) ? 0:dist[i][j]) << " ";
  //   }
  //   cout << endl;
  // }
  // cout << s << endl;
  // cout << plc << endl;
  if(plc.size() == 0){
    cout << 0 << endl;
    return ;
  }
  each(p,plc){
    // cout << s << " " << p << " " << dist[s][p] << endl;
    if(dist[s][p] == INF){
      cout  << -1 << endl;
      return ;
    }
  }
  ll siz = plc.size();
  vector<vector<ll>> dp(1 << siz,vll(siz,INF));
  rep(i,siz){
    dp[1 << i][i] = dist[s][plc[i]];
  }
  // rep(i,1 << siz){
  //   rep(j,siz){
  //     cout << dp[i][j] << " "; 
  //   }
  //   cout << endl;
  // }
  // cout << endl;
  rep(i,1 << siz){
    rep(j,siz){
      if(dp[i][j] == INF)continue;
      rep(k,siz){
        if(~i >> k & 1){
          chmin(dp[i + (1 << k)][k],dp[i][j] + dist[plc[j]][plc[k]]);
        }
      }
    }
  }
  // rep(i,1 << siz){
  //   rep(j,siz){
  //     cout << dp[i][j] << " ";
  //   }
  //   cout << endl;
  // }

  ll ans = INF;
  rep(i,siz){
    chmin(ans,dp[(1 << siz)-1][i]);
  }
  if(ans == INF){
    cout << -1 << endl;
  }else{
    cout << ans << endl;
  }
}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(w,h);//変数数調整
    if(zero(w,h))break;
    solve(w,h);
  }
}
accuracy: 1
time_ms: 2440
memory_kb: 4528
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
int w,h;
string c[20];
void solve(){
  int sx=-1,sy=-1;
  vector<pair<int,int>>dirt;
  for(int i=0;i<h;++i)for(int j=0;j<w;++j){
    if(c[i][j]=='o')sx=i,sy=j;
    if(c[i][j]=='*')dirt.emplace_back(i,j);
  }
  int n=dirt.size();
  dirt.emplace_back(sx,sy);
  vector<vector<int>>dist(n+1,vector<int>(n+1,1<<29));
  for(int i=0;i<n+1;++i){
    for(int j=i+1;j<n+1;++j){
      vector<vector<int>>d(h,vector<int>(w,1<<29));
      auto[sx,sy]=dirt[i];
      d[sx][sy]=0;
      queue<pair<int,int>>que;
      que.push({sx,sy});
      while(!que.empty()){
        auto[x,y]=que.front();
        que.pop();
        int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
        for(int dir=0;dir<4;++dir){
          int xx=x+dx[dir],yy=y+dy[dir];
          if(!(0<=xx&&xx<h&&0<=yy&&yy<w))continue;
          if(c[xx][yy]=='x')continue;
          if(d[xx][yy]!=1<<29)continue;
          d[xx][yy]=d[x][y]+1;
          que.push({xx,yy});
        }
      }
      auto[tx,ty]=dirt[j];
      dist[i][j]=dist[j][i]=d[tx][ty];
    }
  }
  vector<vector<int>>dp(1<<n,vector<int>(n,1<<29));
  for(int i=0;i<n;++i)dp[1<<i][i]=dist[n][i];
  for(int bit=1;bit<1<<n;++bit){
    for(int i=0;i<n;++i){
      if(!(bit&(1<<i)))continue;
      for(int j=0;j<n;++j){
        if(i==j)continue;
        if(bit&(1<<j))continue;
        dp[bit|(1<<j)][j]=min(dp[bit|(1<<j)][j],dp[bit][i]+dist[i][j]);
      }
    }
  }
  int ans=1<<29;
  for(int i=0;i<n;++i)ans=min(ans,dp[(1<<n)-1][i]);
  if(ans==1<<29)ans=-1;
  cout<<ans<<'\n';
}
int main(){
  cin.tie(0)->sync_with_stdio(0);
  while(1){
    cin>>w>>h;
    if(w==0)break;
    for(int i=0;i<h;++i)cin>>c[i];
    solve();
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3512
final_rank: 5