#include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

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

unsigned toHash(int py, int px, vector<pair<int, int> >& rock)
{
    sort(rock.begin(), rock.end());

    unsigned ret = py * 16 + px;
    for(int i=0; i<3; ++i){
        ret *= 16 * 16;
        ret += rock[i].first * 16 + rock[i].second;
    }
    return ret;
}

void fromHash(unsigned hash, int& py, int& px, vector<pair<int, int> >& rock)
{
    rock.resize(3);

    for(int i=2; i>=0; --i){
        rock[i].second = hash % 16;
        hash /= 16;
        rock[i].first = hash % 16;
        hash /= 16;
    }

    px = hash % 16;
    py = hash / 16;
}

int main()
{
    for(;;){
        int h, w;
        cin >> w >> h;
        if(h == 0)
            return 0;

        int py, px;
        vector<pair<int, int> > start, goal;
        vector<string> grid(h, string(w, ' '));

        for(int i=0; i<h; ++i){
            for(int j=0; j<w; ++j){
                cin >> grid[i][j];
                if(grid[i][j] == '@'){
                    py = i;
                    px = j;
                }else if(grid[i][j] == '*'){
                    start.push_back(make_pair(i, j));
                }else if(grid[i][j] == '_'){
                    goal.push_back(make_pair(i, j));
                }
            }
        }
        sort(goal.begin(), goal.end());

        queue<unsigned> q;
        q.push(toHash(py, px, start));
        set<unsigned> history;
        history.insert(toHash(py, px, start));
        int ret = 0;

        for(;;){
            bool ok = false;
            int n = q.size();
            while(--n >= 0){
                int y0, x0;
                vector<pair<int, int> > rock0;
                fromHash(q.front(), y0, x0, rock0);
                q.pop();

                if(rock0 == goal){
                    cout << ret << endl;
                    ok = true;
                    break;
                }

                for(int i=0; i<4; ++i){
                    int y = y0 + dy[i];
                    int x = x0 + dx[i];
                    if(grid[y][x] == '#')
                        continue;

                    vector<pair<int, int> > rock = rock0;
                    vector<pair<int, int> >::iterator it = find(rock.begin(), rock.end(), make_pair(y, x));
                    if(it != rock.end()){
                        it->first  += dy[i];
                        it->second += dx[i];
                        if(grid[it->first][it->second] == '#' || count(rock.begin(), rock.end(), *it) > 1)
                            continue;
                    }

                    unsigned hash = toHash(y, x, rock);
                    if(history.find(hash) == history.end()){
                        q.push(hash);
                        history.insert(hash);
                    }
                }
            }

            if(ok)
                break;
            ++ ret;
        }
    }
}

Measured memory_bytes: 20808