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

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
int n, m;
char c[20][20];

pair<int, int> pp[20];

bool vis[20][20];

char mx='0';

void bfs()
{
	queue<pair<int, pair<int, int> > > q;
	q.push (make_pair (0, make_pair (pp[1].first, pp[1].second)));
	while (!q.empty())
	{
		pair<int, pair<int, int> > p = q.front();
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			int ax = p.second.first + dx[i];
			int ay = p.second.second + dy[i];
			if (ax >= 0 && ax < n && ay >= 0 && ay < m && !vis[ax][ay] && c[ax][ay] != '#')
			{
				if (isdigit (c[ax][ay]) && (pp[mx - '0'].first != ax || pp[mx - '0'].second != ay)) continue;
				if (c[ax][ay] == '@')
				{
					cout << p.first + 1 << endl;
					return ;
				}
				else
				{
					for(int k=mx-'0';k>=2;k--)
					{
						pp[k].first = pp[k-1].first;
						pp[k].second = pp[k-1].second;
					}
					q.push (make_pair (p.first + 1, make_pair(ax, ay)));
					vis[ax][ay] = 1;
				}
			}
		}
	}
	cout<<-1<<endl;
}

int main()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> c[i][j];
			if (isdigit(c[i][j]))
			{
				pp[c[i][j] - '0'] = make_pair (i, j);
				mx = max (mx, c[i][j]);
			}
		}
	}
	bfs();
	return 0;
}


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

struct point
{
	int x,y;
};
struct node
{
	point snake[11];
	int k;
	char map[16][16];
};
bool b[2][16][16];
int maxx=0;
queue<node>Q;
int var[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int main()
{
	//freopen("1.out","w",stdout);
	memset(b,0,sizeof(b));
	long long n,m;
	cin>>n>>m;
	node tmp;
	point food;
	char c;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			cin>>c;
			if(c>='1'&&c<='9')
			{
				tmp.map[i][j]=c;
				int v=c-'0';
				tmp.snake[v].x=i;
				tmp.snake[v].y=j;
				//cout<<v<<endl;
				if(v>maxx)maxx=v;
			}
			else if(c=='@')
			{
				food.x=i;
				food.y=j;
				tmp.map[i][j]=c;
			}
			else
			{
				tmp.map[i][j]=c;
			}
		}
	tmp.k=0;
//	cout<<food.x<<" "<<food.y<<endl;
//	cout<<maxx<<endl;
//	for(int i=1;i<=n;i++)
//	{
//		for(int j=1;j<=m;j++)cout<<tmp.map[i][j];
//		cout<<endl;
//	}
	Q.push(tmp);
	while(!Q.empty())
	{
		node cur=Q.front();Q.pop();
		//for(int i=1;i<=maxx;i++)cout<<cur.snake[i].x<<" "<<cur.snake[i].y<<endl;
		//cout<<"SB"<<cur.k<<endl;
		int x=cur.snake[1].x,y=cur.snake[1].y;
		if(x==food.x&&y==food.y)
		{
			cout<<cur.k;
			return 0;
		}
		if(cur.k==10)break;
		node tmp=cur;

		cur.map[cur.snake[maxx].x][cur.snake[maxx].y]=tmp.map[cur.snake[maxx].x][cur.snake[maxx].y]='.';
		for(int i=maxx;i>=1;i--)
		{
			tmp.snake[i]=tmp.snake[i-1];
		}
		tmp.k++;
		for(int i=0;i<=3;i++)
		{
			if
			(
				(x+var[i][0]>0&&x+var[i][0]<=n&&y+var[i][1]>0&&y+var[i][1]<=m)
			&&
				(cur.map[x+var[i][0]][y+var[i][1]]=='.'||cur.map[x+var[i][0]][y+var[i][1]]=='@')
			/*&&
				(!b[0][x+var[i][1]][y+var[i][1]]||!b[1][cur.snake[maxx].x][cur.snake[maxx].y])*/
			)
			{
				/*b[0][x+var[i][0]][y+var[i][1]]=1;
				b[1][cur.snake[maxx].x][cur.snake[maxx].y]=1;*/
				tmp.snake[1].x=x+var[i][0];tmp.snake[1].y=y+var[i][1];
				tmp.map[x+var[i][0]][y+var[i][1]]='#';
				Q.push(tmp);
				tmp.map[x+var[i][0]][y+var[i][1]]='.';
			}
		}
	}
	cout<<-1;
	return 0;
}


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

int n,m,x_,y_,cnt,ans=-1;
char snack_map[16][16];
int dx[5]= {0,1,-1,0,0};
int dy[5]= {0,0,0,1,-1};

struct node {
	int step;
	int x,y;
	int X[10],Y[10];
} note;

bool flag;

queue<node> q;

void BFS() {
	note.step=0;
	note.x=x_;
	note.y=y_;
	q.push(note);
	while(!q.empty()) {
		//cout<<1;
		node u=q.front();
		q.pop();
		if(u.step==16)
	{
		flag=true;
		return;
	}
		u.X[cnt]=-1;
		u.Y[cnt]=-1;
		if(snack_map[u.x][u.y]=='@') {
			ans=u.step;
			printf("%d\n",u.step);
			return;
		}
		for(int i=1; i<=4; i++) {
			int xx=u.x+dx[i];
			int yy=u.y+dy[i];
			if(snack_map[xx][yy]=='.'||snack_map[xx][yy]=='@') {
				for(int j=cnt; j>1; j--) {
					note.X[j]=u.X[j-1],note.Y[j]=u.Y[j-1];
				}
				note.x=xx;
				note.y=yy;
				note.step=u.step+1;
				q.push(note);
			}
			/*cout<<endl;
			for(int i=1; i<=n; i++) {
				for(int j=1; j<=m; j++) {
					if(i==xx&&j==yy||i==note.X[2]&&j==note.Y[2]||i==note.X[3]&&j==note.Y[3]||i==note.X[4]&&j==note.Y[4])
						cout<<'*';
					else
						cout<<snack_map[i][j];
				}
				cout<<endl;
			}
			cout<<endl;*/
		}
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=9; i++) {
		note.X[i]=-1,note.Y[i]=-1;
	}
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			cin>>snack_map[i][j];
			if(snack_map[i][j]=='1') {
				x_=i;
				y_=j;
			}
			if(snack_map[i][j]>='1'&&snack_map[i][j]<='9')
			cnt++;
			if(snack_map[i][j]=='2')	note.X[2]=i,note.Y[2]=j;
			if(snack_map[i][j]=='3')	note.X[3]=i,note.Y[3]=j;
			if(snack_map[i][j]=='4')	note.X[4]=i,note.Y[4]=j;
			if(snack_map[i][j]=='5')	note.X[5]=i,note.Y[5]=j;
			if(snack_map[i][j]=='6')	note.X[6]=i,note.Y[6]=j;
			if(snack_map[i][j]=='7')	note.X[7]=i,note.Y[7]=j;
			if(snack_map[i][j]=='8')	note.X[8]=i,note.Y[8]=j;
			if(snack_map[i][j]=='9')	note.X[9]=i,note.Y[9]=j;
		}
	}
	BFS();
	if(flag) cout<<-1;
}


#include <cstdio>//第一个版本纯原创，这是根据rk1的程序做了优化，大体思路不变
using namespace std;
struct node
{int x,y,body,step;}f[1968301];
bool vi[16][16][65536],use[16][16];
int m,n,stx,sty,ans=-1,dis,q;
int mx[4]={-1,1,0,0},my[4]={0,0,-1,1};
char a[16][16];
void read(int p)
{	char x=' ';
	while(x=='\n'||x=='\r'||x==' ')
	x=getchar();
	for(int i=1;i<=n;i++)
	{	a[p][i]=x;
		if(x=='1')
		{	f[1].x=p;f[1].y=i;}
		if(x>='1'&&x<='9'&&x-'0'>dis)
		dis=x-'0';
		x=getchar();
	}
}
int build(int lx,int ly,char p)
{	int x,y;
	for(int i=0;i<4;i++)
	{	x=lx+mx[i];y=ly+my[i];
		if(x<1||x>m||y<1||y>n) continue;
		if(a[x][y]==p)
		return (build(x,y,p+1)<<2)|i;
	}
	return 0;
}
void update(int num,bool v)
{	int x=f[num].x,y=f[num].y,z=f[num].body,p;
	for(int i=1;i<dis;i++)
	{	use[x][y]=v;
		p=z&3;z>>=2;
//		printf("x=%d y=%d p=%d z=%d\n",x,y,p,z);
		x+=mx[p];y+=my[p];
	}
}
void output()
{	for(int i=1;i<=m;i++)
	{	for(int j=1;j<=n;j++)
		printf("%d",use[i][j]);
		printf("\n");
	}
	printf("\n");
}
void bfs()
{	int l=1,r=2,x,y,z;
	f[1].body=build(f[1].x,f[1].y,'2');
//	printf("%d %d %d\n",f[1].x,f[1].y,f[1].body);
	vi[f[1].x][f[1].y][f[1].body]=true;
	while(l<r)
	{//	printf("l:%d r:%d\n",l,r);
		update(l,1);
//		output();
		for(int i=0;i<4;i++)
		{	x=f[l].x+mx[i];
			y=f[l].y+my[i];
			if(x<1||x>m||y<1||y>n) continue;
			if(a[x][y]=='#') continue;
			if(use[x][y]) continue;
			if(a[x][y]=='@')
			{	ans=f[l].step+1;return;}
			z=f[l].body<<2;
			z&=q;
			z|=i^1;
	//		printf("x=%d y=%d z=%d\n",x,y,z);
			if(vi[x][y][z]) continue;
			vi[x][y][z]=true;
			f[r].x=x;f[r].y=y;
			f[r].step=f[l].step+1;
			f[r].body=z;
			r++;
		}
		update(l,0);l++;
//		printf("2l:%d r:%d\n",l,r);
	}
}
int main()
{	scanf("%d %d",&m,&n);
	for(int i=1;i<=m;i++)
	read(i);
	q=(1<<(2*dis-2))-1;
	bfs();
	printf("%d",ans);
	return 0;
}


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

char a[20][20];
int premask,vis[16][16][65536];
int n,m,k;
int go[4][2]= {{-1,0},{0,1},{1,0},{0,-1}};

struct snake
{
	int x,y,mask;
	snake() {};
	snake(int X,int Y,int Mask)
	{
		x=X,y=Y,mask=Mask;
	}
};

int find(int x,int y,char cur)
{
	if(a[x-1][y]==cur+1) return 0;
	if(a[x][y+1]==cur+1) return 1;
	if(a[x+1][y]==cur+1) return 2;
	if(a[x][y-1]==cur+1) return 3;
}

bool judge(int tx,int ty,snake cur)
{
	int x=cur.x,y=cur.y,mask=cur.mask;
	for(int i=1; i<=k-2; i++,mask>>=2)
	{
		x+=go[mask%4][0];
		y+=go[mask%4][1];
		if(x==tx && y==ty) return true;
	}
	return false;
}

int main()
{
	//freopen("snake.in","r",stdin);
	scanf("%d %d\n",&n,&m);
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			scanf("%c",&a[i][j]);
			if(a[i][j]>='1' && a[i][j]<='9')
				k=max(k,a[i][j]-'0');
		}
		scanf("\n");
	}
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
		{
			if(a[i][j]>='1' && a[i][j]<k+'0')
				premask|=(find(i,j,a[i][j])<<(2*(a[i][j]-'1')));
		}
	queue<pair<snake,int> >Q;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++)
			if(a[i][j]=='1')
			{
				vis[i][j][premask]=1;
				Q.push(pair<snake,int> {snake(i,j,premask),0});
			}
	int ans=-1;
	while(!Q.empty())
	{
		pair<snake,int>cur=Q.front();
		Q.pop();
		if(a[cur.first.x][cur.first.y]=='@')
		{
			ans=cur.second;
			break;
		}
		for(int i=0; i<=3; i++)
		{
			int tx=cur.first.x+go[i][0];
			int ty=cur.first.y+go[i][1];
			int newmask=((cur.first.mask&((1<<(2*k-4))-1))<<2)|(i^2);
			if(a[tx][ty]=='#' || tx<1 || tx>n || ty<1 || ty>m || vis[tx][ty][newmask]) continue;
			if(judge(tx,ty,cur.first)) continue;
			vis[tx][ty][newmask]=1;
			Q.push(pair<snake,int> {snake(tx,ty,newmask),cur.second+1});
		}
	}
	printf("%d",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,len=1;
int xx[4]={1,0,-1,0},yy[4]={0,-1,0,1};
char mp[17][17];
struct snake
{
	int head_x,head_y,body;
	bool operator< (const snake& P)const
	{
		if(head_x==P.head_x)
		{
			if(head_y==P.head_y)
				return body<P.body;
			return head_y<P.head_y;
		}
		return head_x<P.head_x;
	}
	bool legal()
	{
		if(head_x<1 || head_x>n || head_y<1 || head_y>m)return 0;
		if(mp[head_x][head_y]=='#')return 0;
		int nowx=head_x,nowy=head_y;
		for(int i=len-1;i>=1;i--)
		{
			nowx+=xx[(body>>2*i-2)&3];
			nowy+=yy[(body>>2*i-2)&3];
			if(nowx==head_x && nowy==head_y)return 0;
		}
		return 1;
	}
};
map<snake,int> used;
queue<snake> q;
int main()
{
	snake start;
	int tox=0,toy=0;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%s",mp[i]+1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			if(mp[i][j]=='1')
			{
				start.head_x=i;
				start.head_y=j;
				int nowx=i,nowy=j;
again:			for(int k=0;k<4;k++)
					if(mp[nowx+xx[k]][nowy+yy[k]]==mp[nowx][nowy]+1)
					{
						start.body=(start.body<<2)|k;
						nowx+=xx[k];
						nowy+=yy[k];
						len++;
						goto again;
					}
			}
			else if(mp[i][j]=='@')
			{
				tox=i;
				toy=j;
			}
		}
	q.push(start);
	used[start]=0;
	while(!q.empty())
	{
		snake now=q.front();q.pop();
		int ans=used[now];
//		printf("%d %d %d\n",now.head_x,now.head_y,now.body);
		if(now.head_x==tox && now.head_y==toy)
		{
			printf("%d\n",ans);
			return 0;
		}
		for(int i=0;i<4;i++)
		{

			snake to=now;
			to.head_x+=xx[i];
			to.head_y+=yy[i];
			to.body>>=2;
			to.body|=(i+2)%4<<len*2-4;
			if(used[to] || !to.legal())continue;
			q.push(to);
			used[to]=ans+1;
		}
	}
	puts("-1");
	return 0;
}


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

int n,m,x_,y_,cnt,ans=-1;
char snack_map[16][16];
int dx[5]= {0,1,-1,0,0};
int dy[5]= {0,0,0,1,-1};

struct node {
	int step;
	int x,y;
	int X[10],Y[10];
} note;

bool flag;

queue<node> q;

void BFS() {
	note.step=0;
	note.x=x_;
	note.y=y_;
	q.push(note);
	while(!q.empty()) {
		//cout<<1;
		node u=q.front();
		q.pop();
		/*if(u.step==16)
	{
		flag=true;
		return;
	}*/
		u.X[cnt]=-1;
		u.Y[cnt]=-1;
		if(snack_map[u.x][u.y]=='@') {
			ans=u.step;
			printf("%d\n",u.step);
			return;
		}
		for(int i=1; i<=4; i++) {
			int xx=u.x+dx[i];
			int yy=u.y+dy[i];
			if(snack_map[xx][yy]=='.'||snack_map[xx][yy]=='@') {
				for(int j=cnt; j>1; j--) {
					note.X[j]=u.X[j-1],note.Y[j]=u.Y[j-1];
				}
				note.x=xx;
				note.y=yy;
				note.step=u.step+1;
				q.push(note);
			}
			/*cout<<endl;
			for(int i=1; i<=n; i++) {
				for(int j=1; j<=m; j++) {
					if(i==xx&&j==yy||i==note.X[2]&&j==note.Y[2]||i==note.X[3]&&j==note.Y[3]||i==note.X[4]&&j==note.Y[4])
						cout<<'*';
					else
						cout<<snack_map[i][j];
				}
				cout<<endl;
			}
			cout<<endl;*/
		}
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=9; i++) {
		note.X[i]=-1,note.Y[i]=-1;
	}
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			cin>>snack_map[i][j];
			if(snack_map[i][j]=='1') {
				x_=i;
				y_=j;
			}
			if(snack_map[i][j]>='1'&&snack_map[i][j]<='9')
			cnt++;
			if(snack_map[i][j]=='2')	note.X[2]=i,note.Y[2]=j;
			if(snack_map[i][j]=='3')	note.X[3]=i,note.Y[3]=j;
			if(snack_map[i][j]=='4')	note.X[4]=i,note.Y[4]=j;
			if(snack_map[i][j]=='5')	note.X[5]=i,note.Y[5]=j;
			if(snack_map[i][j]=='6')	note.X[6]=i,note.Y[6]=j;
			if(snack_map[i][j]=='7')	note.X[7]=i,note.Y[7]=j;
			if(snack_map[i][j]=='8')	note.X[8]=i,note.Y[8]=j;
			if(snack_map[i][j]=='9')	note.X[9]=i,note.Y[9]=j;
		}
	}
	BFS();
	if(flag) cout<<-1;
}


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

int n,m,cnt;
char snack_map[16][16];
int dx[5]= {0,1,-1,0,0};
int dy[5]= {0,0,0,1,-1};

queue<vector<int>> q;

map<vector<int>,int> jh;

vector<int> use;

void BFS() {
	q.push(use);
	jh[use]=0;
	while(!q.empty()) {
		vector<int> u=q.front();
		q.pop();
		int step=jh[u];
		for(int i=1; i<=4; i++) {
			int x=u[0]+dx[i];
			int y=u[1]+dy[i];
			if(x<=0||x>n||y<=0||y>m||snack_map[x][y]=='#') {
				continue;
			}
			bool body=false;
			for(int j=1; j<=cnt-1; j++) {
				if(x==u[2*j]&&y==u[2*j+1]) {
					body=true;
				}
			}
			if(body) continue;
			if(snack_map[x][y]=='@') {
				cout<<step+1;
				exit(0);
			}

			vector<int> p(2*cnt);
			p[0]=x;
			p[1]=y;
			for(int j=1; j<=2*cnt-2;j++) p[2+j]=u[j];
			if(jh.find(p)==jh.end()) {
				jh[p]=step+1;
				q.push(p);
			}
		}
	}
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>snack_map[i][j];
		}
	}
	for(int i=0;; i++) {
		bool flag=false;
		for(int j=1; j<=n; j++) {
			for(int k=1; k<=m; k++) {
				if(snack_map[j][k]=='1'+i) {
					flag=true;
					cnt++;
					use.push_back(j);
					use.push_back(k);
				}
			}
		}
		if(!flag) break;
	}
	BFS();
	cout<<-1;
	return 0;
}


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

int n,m,cnt;
char snack_map[17][17];
int dx[5]= {0,1,-1,0,0};
int dy[5]= {0,0,0,1,-1};
bool use1[17][17];

queue<vector<int>> q;

map<vector<int>,int> jh;

vector<int> use;

void dfs(int x, int y) {
	if(x <= 0 || x > n || y <= 0 || y > m || snack_map[x][y] == '#' || use1[x][y]) return;
	use1[x][y] = true;
	for(int i=1; i<=4; i++) dfs(x+dx[i], y+dy[i]);
}

int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			cin>>snack_map[i][j];
		}
	}
	for(int i=0;; i++) {
		bool flag=false;
		for(int j=1; j<=n; j++) {
			for(int k=1; k<=m; k++) {
				if(snack_map[j][k]=='1'+i) {
					flag=true;
					cnt++;
					use.push_back(j);
					use.push_back(k);
				}
			}
		}
		if(!flag) break;
	}

	dfs(use[0], use[1]);
	bool can = false;
	for(int i=1; i<=n; i++) {
		for(int j=1; j<=m; j++) {
			if(snack_map[i][j] == '@' && use1[i][j]) can = true;
		}
	}
	if(!can) {
		cout << -1 << endl;
		return 0;
	}

	q.push(use);
	jh[use]=0;
	while(!q.empty()) {
		vector<int> u=q.front();
		q.pop();
		int step=jh[u];
		for(int i=1; i<=4; i++) {
			int x=u[0]+dx[i];
			int y=u[1]+dy[i];
			if(x<=0||x>n||y<=0||y>m) {
				continue;
			}
			if(snack_map[x][y]=='#')
			continue;
			bool body=false;
			for(int j=0; j<cnt-1; j++) {
				if(x==u[2*j]&&y==u[2*j+1]) {
					body=true;
				}
			}
			if(body) continue;
			if(snack_map[x][y]=='@') {
				cout<<step+1<<endl;
				return 0;
			}
			vector<int> p(2*cnt);
			p[0]=x;
			p[1]=y;
			for(int j=0; j<2*cnt-2; j++) p[2+j]=u[j];
			if(jh.find(p)==jh.end()) {
				jh[p]=step+1;
				q.push(p);
			}
		}
	}
	cout<<-1;
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=20;
char g[maxn][maxn];
int ax,ay,sx,sy;
int N,M,len;
bool vis[20000010];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
struct node
{
    int x[10],y[10];
    int step;
    node(){step=0;}
};
int find(node a,int i)
{
    for(int j=0;j<4;j++)
    {
        int x=a.x[i-1]+dx[j];
        int y=a.y[i-1]+dy[j];
        if(x==a.x[i]&&y==a.y[i])return j;
    }
}
int gethash(int sx,int sy,node a)
{
    int hash=sx*M+sy;
    for(int i=1;i<len;i++)
        hash=hash*4+find(a,i);
    return hash;
}

void solve(node s)
{
    queue<node> q;
    s.step=0;
    q.push(s);
    while(!q.empty())
    {
        node a=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            int x=a.x[0]+dx[i];
            int y=a.y[0]+dy[i];
            if(x<1||x>N||y<1||y>M||g[x][y]=='#')continue;
            bool flag=true;
            for(int j=1;j<len-1;j++)
                if(x==a.x[j]&&y==a.y[j])
                    {flag=false;break;}
            if(!flag)continue;
            node tmp;
            tmp.x[0]=x,tmp.y[0]=y;
            for(int j=1;j<len;j++)
            {
                tmp.x[j]=a.x[j-1];
                tmp.y[j]=a.y[j-1];
            }
            int hash=gethash(x,y,tmp);
            if(!vis[hash])
            {
                tmp.step=a.step+1;
                vis[hash]=1;
                q.push(tmp);
            }
            if(x==ax&&y==ay){printf("%d\n",tmp.step);return;}
        }
    }
    printf("-1\n");
}
int main(int argc,char**argv)
{
    scanf("%d%d",&N,&M);
    node s;
    for(int i=1;i<=N;i++)
    {
        scanf("%s",g[i]+1);
        for(int j=1;j<=M;j++)
        {
            if(g[i][j]=='@')ax=i,ay=j;
            else if(g[i][j]>='1'&&g[i][j]<='9')
            {
                if(g[i][j]=='1')sx=i,sy=j;
                s.x[g[i][j]-'1']=i;
                s.y[g[i][j]-'1']=j;
                len++;
                g[i][j]='.';
            }
        }
    }
    int tmp=gethash(sx,sy,s);
    vis[tmp]=1;
    solve(s);
    return 0;
}


#include<map>
#include<queue>
#include<cstdio>
inline int in();
inline void wr(int);
const int N=(int)2e1+5;
char ju[N][N];int n,m,a[N],dis[N][N];
inline bool check(char);
struct Node{
	int x[N],y[N],stp;
	friend bool operator <(const Node&p,const Node&q){
		if(p.stp!=q.stp)return p.stp>q.stp;
		return dis[p.x[1]][p.y[1]]>dis[q.x[1]][q.y[1]];
	}
	friend bool operator >(const Node&p,const Node&q){
		if(p.stp!=q.stp)return p.stp<q.stp;
		return dis[p.x[1]][p.y[1]]<dis[q.x[1]][q.y[1]];
	}
};
std::map<Node,int>dp;
struct Edge{
	int x,y,val;
};
const int dx[]={-1,0,1,0};
const int dy[]={0,-1,0,1};
inline int ab(int);
inline void bfs(int,int,int);
inline void juuuuu();
int main(int argc,char**argv){
	n=in(),m=in();
	register int ex=-1,ey=-1;
	for(register int i=1;i<=n;++i)
		for(register int j=1;j<=m;++j){
			while(check(ju[i][j]))
				ju[i][j]=getchar();
			if(ju[i][j]=='@')ex=i,ey=j;
		}
	register Node s;s.stp=1;
	register int len=0;
	for(register int i=1;i<=9;++i){
		register bool tp=1;
		for(register int j=1;j<=n&&tp;++j)
			for(register int k=1;k<=m&&tp;++k)
				if(ju[j][k]==i+'0')s.x[i]=j,s.y[i]=k,tp=0;
		if(tp){len=i-1;break;}
		else if(i==9){len=9;break;}
	}
	if(s.x[1]==ex&&s.y[1]==ey){wr(0);return 0;}
	bfs(ex,ey,1);
	std::priority_queue<Node>queue;
	queue.push(s);dp[s]=1;
	while(!queue.empty()){
		register Node u=queue.top();
		queue.pop();
		for(register int k=0;k<4;++k){
			register int nx=u.x[1]+dx[k],ny=u.y[1]+dy[k];
			if(nx==ex&&ny==ey){wr(u.stp);return 0;}
			if(nx<1||nx>n||ny<1||ny>m)continue;
			if(ju[nx][ny]=='#')continue;
			register bool tp=1;
			for(register int i=2;i<len&&tp;++i)
				if(u.x[i]==nx&&u.y[i]==ny)tp=0;
			if(tp){
				register Node v;
				for(register int i=1;i<len;++i)
					v.x[i+1]=u.x[i],v.y[i+1]=u.y[i];
				v.x[1]=nx,v.y[1]=ny;v.stp=u.stp+1;
				queue.push(v),dp[v]=v.stp;
			}
		}
	}
	puts("-1");
}
inline void bfs(int x,int y,int val){
	dis[x][y]=val;
	std::queue<Edge>queue;
	queue.push((Edge){x,y,val});
	while(!queue.empty()){
		register Edge u=queue.front();
		queue.pop();
		for(register int k=0;k<4;++k){
			register int nx=u.x+dx[k],ny=u.y+dy[k];
			if(nx<1||nx>n||ny<1||ny>m)continue;
			if(ju[nx][ny]=='#')continue;
			if(!dis[nx][ny]){
				dis[nx][ny]=dis[x][y]+1;
				queue.push((Edge){nx,ny,dis[nx][ny]});
			}
		}
	}
}
inline bool check(char c){
	return c!='#'&&c!='@'&&c!='.'&&(c<'0'||c>'9');
}
inline int ab(int x){
	return x<0?-x:x;
}
inline int in(){
	register char c=getchar();
	register int x=0,f=1;
	for(;c<'0'||c>'9';c=getchar())
		if(c=='-')f=-1;
	for(;c>='0'&&c<='9';c=getchar())
		x=(x<<1)+(x<<3)+(c&15);
	return x*f;
}
inline void wr(int x){
	if(x<0)putchar('-'),x=-x;
	if(x/10)wr(x/10);
	putchar(x%10+'0');
}


#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
int K;
int dp[15][15][1<<16];
string fld[15];
int encode(vector<int> px,vector<int> py){
	int c=0;
	for(int i=0;i<K-1;i++){
		int dir;
		for(dir=0;dir<4;dir++){
			if(px[i]+dx[dir]==px[i+1]&&py[i]+dy[dir]==py[i+1]){
				break;
			}
		}
		c|=dir<<(2*i);
	}
	return c;
}
void decode(int c,int x,int y,vector<int>& px,vector<int>& py){
	px.resize(K);
	py.resize(K);
	px[0]=x;
	py[0]=y;
	for(int i=0;i<K-1;i++){
		int d=(c>>(2*i))&3;
		px[i+1]=px[i]+dx[d];
		py[i+1]=py[i]+dy[d];
	}
}
string gr[15];
int main(){
	cin>>n>>m;
	memset(dp,-1,sizeof(dp));
	vector<int>sx,sy;
	int tx,ty;
	int gx,gy;
	for(int i=0;i<n;i++){
		cin>>fld[i];
		for(int j=0;j<m;j++){
			if(isdigit(fld[i][j])){
				if(fld[i][j]=='1'){
					tx=i;ty=j;
				}
				int s=fld[i][j]-'1';
				if(s+1>K){
					K=s+1;
					sx.resize(K);
					sy.resize(K);
				}
				sx[s]=i;
				sy[s]=j;
				fld[i][j]='.';
			}
			else if(fld[i][j]=='@'){
				gx=i;gy=j;
				fld[i][j]='.';
			}
		}
	}
//	cout<<tx<<' '<<ty<<' '<<gx<<' '<<gy<<endl;
//	for(int i=0;i<K;i++)cout<<sx[i]<<' ';cout<<endl;
//	for(int i=0;i<K;i++)cout<<sy[i]<<' ';cout<<endl;
	queue<int>q;
	int tc=encode(sx,sy);
	q.push(tx);q.push(ty);q.push(tc);
	dp[tx][ty][tc]=0;
	int l=0;
	while(!q.empty()){
		int hx=q.front();q.pop();
		int hy=q.front();q.pop();
		int hc=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<hx<<' '<<hy<<' '<<hc<<' '<<dp[hx][hy][hc]<<endl;
//		for(int i=0;i<n;i++)gr[i]=fld[i];
		vector<int>px,py;
		decode(hc,hx,hy,px,py);
//		for(int i=0;i<K;i++){
//			gr[px[i]][py[i]]=i+'1';
//		}
//		for(int i=0;i<n;i++)cout<<gr[i]<<endl;cout<<endl;
		for(int i=K;i>0;i--){
			px[i]=px[i-1];
			py[i]=py[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=hx+dx[i];
			int ny=hy+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&fld[nx][ny]=='.'){
				if(nx==gx&&ny==gy){
					cout<<dp[hx][hy][hc]+1<<endl;
					return 0;
				}
				bool die=false;
				for(int i=1;i<K;i++){
					if(nx==px[i]&&ny==py[i]){
						die=true;
						break;
					}
				}
				if(die)continue;
				px[0]=nx;
				py[0]=ny;
				int nc=encode(px,py);
				if(dp[nx][ny][nc]==-1||dp[nx][ny][nc]>dp[hx][hy][hc]+1){
					dp[nx][ny][nc]=dp[hx][hy][hc]+1;
					q.push(nx);q.push(ny);q.push(nc);
				}
			}
		}
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m,len;
char a[15][15];
struct State{
	char b[15][15];
	int steps;
	int hash(){
		int p=0;
		rep(i,n)rep(j,m)p=p*171+b[i][j];
		return p;
	}
	void takeout(char x){
		rep(i,n)rep(j,m)if(b[i][j]==x)b[i][j]='.';
	}
	void increase(){
		rep(i,n)rep(j,m)if(b[i][j]>='1'&&b[i][j]<='8')b[i][j]++;
	}
};
set<int>vis;
queue<State>q;
int ans=-1;
bool inrange(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
void move(State &state){
	state.steps++;
	rep(i,n)rep(j,m)if(state.b[i][j]=='2'){
		rep(f,4){
			int dx=i+xx[f];
			int dy=j+yy[f];
			if(inrange(dx,dy)){
				if(state.b[dx][dy]=='@'){
					ans=state.steps;
					return;
				}
				if(state.b[dx][dy]=='.'){
					state.b[dx][dy]='1';
					int h=state.hash();
					if(vis.find(h)==vis.end()){
						vis.insert(h);
						q.push(state);
					}
					state.b[dx][dy]='.';
				}
			}
		}
		return;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	rep(i,n)scanf("%s",a[i]);
	rep(i,n)rep(j,m)if(a[i][j]>='3'&&a[i][j]<='9')len=max(len,a[i][j]-'0');
	State init;
	rep(i,n)rep(j,m)init.b[i][j]=a[i][j];
	init.steps=0;
	vis.insert(init.hash());
	q.push(init);
	while(!q.empty()&&ans==-1){
		State state=q.front();q.pop();
		state.takeout(len+'0');
		state.increase();
		move(state);
	}
	printf("%d\n",ans);
	return 0;
}


#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
int K;
int dp[15][15][1<<16];
string fld[15];
int encode(vector<int> px,vector<int> py){
	int c=0;
	for(int i=0;i<K-1;i++){
		int dir;
		for(dir=0;dir<4;dir++){
			if(px[i]+dx[dir]==px[i+1]&&py[i]+dy[dir]==py[i+1]){
				break;
			}
		}
		c|=dir<<(2*i);
	}
	return c;
}
void decode(int c,int x,int y,vector<int>& px,vector<int>& py){
	px.resize(K);
	py.resize(K);
	px[0]=x;
	py[0]=y;
	for(int i=0;i<K-1;i++){
		int d=(c>>(2*i))&3;
		px[i+1]=px[i]+dx[d];
		py[i+1]=py[i]+dy[d];
	}
}
string gr[15];
int main(){
	cin>>n>>m;
	memset(dp,-1,sizeof(dp));
	vector<int>sx,sy;
	int tx,ty;
	int gx,gy;
	for(int i=0;i<n;i++){
		cin>>fld[i];
		for(int j=0;j<m;j++){
			if(isdigit(fld[i][j])){
				if(fld[i][j]=='1'){
					tx=i;ty=j;
				}
				int s=fld[i][j]-'1';
				if(s+1>K){
					K=s+1;
					sx.resize(K);
					sy.resize(K);
				}
				sx[s]=i;
				sy[s]=j;
				fld[i][j]='.';
			}
			else if(fld[i][j]=='@'){
				gx=i;gy=j;
				fld[i][j]='.';
			}
		}
	}
//	cout<<tx<<' '<<ty<<' '<<gx<<' '<<gy<<endl;
//	for(int i=0;i<K;i++)cout<<sx[i]<<' ';cout<<endl;
//	for(int i=0;i<K;i++)cout<<sy[i]<<' ';cout<<endl;
	queue<int>q;
	int tc=encode(sx,sy);
	q.push(tx);q.push(ty);q.push(tc);
	dp[tx][ty][tc]=0;
	int l=0;
	while(!q.empty()){
		int hx=q.front();q.pop();
		int hy=q.front();q.pop();
		int hc=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<hx<<' '<<hy<<' '<<hc<<' '<<dp[hx][hy][hc]<<endl;
//		for(int i=0;i<n;i++)gr[i]=fld[i];
		vector<int>px,py;
		decode(hc,hx,hy,px,py);
//		for(int i=0;i<K;i++){
//			gr[px[i]][py[i]]=i+'1';
//		}
//		for(int i=0;i<n;i++)cout<<gr[i]<<endl;cout<<endl;
		for(int i=K-1;i>0;i--){
			px[i]=px[i-1];
			py[i]=py[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=hx+dx[i];
			int ny=hy+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&fld[nx][ny]=='.'){
				if(nx==gx&&ny==gy){
					cout<<dp[hx][hy][hc]+1<<endl;
					return 0;
				}
				bool die=false;
				for(int i=1;i<K;i++){
					if(nx==px[i]&&ny==py[i]){
						die=true;
						break;
					}
				}
				if(die)continue;
				px[0]=nx;
				py[0]=ny;
				int nc=encode(px,py);
				if(dp[nx][ny][nc]==-1||dp[nx][ny][nc]>dp[hx][hy][hc]+1){
					dp[nx][ny][nc]=dp[hx][hy][hc]+1;
					q.push(nx);q.push(ny);q.push(nc);
				}
			}
		}
	}
	cout<<-1<<endl;
	return 0;
}


#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXS=2e7+5,mod=1e6+7;
ll val[MAXS];
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
};
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*24412+u.x[i])*24412+u.y[i])%1000000007;
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
queue<node>q;
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					q.push(nwn);
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q.push(start);
//	int l=0;
	while(!q.empty()){
		node u=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
	}
	cout<<-1<<endl;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define vi vector<int>
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXM=14745600;
int dist[MAXM];
char fld[15][15];
int encode(vi x,vi y){
	int ret=0;
	for(int i=len-1;i>=1;i--){
		int dir;
		for(dir=0;dir<4;dir++){
			if(x[i]+dx[dir]==x[i+1]&&y[i]+dy[dir]==y[i+1]){
				break;
			}
		}
		ret*=4;
		ret+=dir;
	}
	ret*=15;ret+=x[1];
	ret*=15;ret+=y[1];
	return ret;
}
void decode(int ret,vi &x,vi &y){
	x.resize(len+1);
	y.resize(len+1);
	y[1]=ret%15;ret/=15;
	x[1]=ret%15;ret/=15;
	for(int i=2;i<=len;i++){
		int dir=ret%4;ret/=4;
		x[i]=x[i-1]+dx[dir];
		y[i]=y[i-1]+dy[dir];
	}
}
int bfs(vi sx,vi sy){
	memset(dist,-1,sizeof(dist));
	queue<int>q;
	int t1=encode(sx,sy);
	dist[t1]=0;
	q.push(t1);
	int l=0;
	while(!q.empty()){
		int ret=q.front();q.pop();
		vi x,y;
		decode(ret,x,y);
//		l++;
//		printf("Case#%d :\n",l);
//		int gr[15][15];
//		for(int i=0;i<n;i++)for(int j=0;j<m;j++)gr[i][j]=fld[i][j];
//		for(int i=1;i<=len;i++){
//			gr[x[i]][y[i]]=i+'0';
//		}
//		for(int i=0;i<n;i++){
//			for(int j=0;j<m;j++){
//				printf("%c",gr[i][j]);
//			}
//			printf("\n");
//		}
//		printf("\n");
		for(int i=len;i>1;i--){
			x[i]=x[i-1];
			y[i]=y[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=x[2]+dx[i];
			int ny=y[2]+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&fld[nx][ny]!='#'){
				if(fld[nx][ny]=='@'){
					return dist[ret]+1;
				}
				bool die=false;
				for(int i=2;i<=len;i++){
					if(nx==x[i]&&ny==y[i]){
						die=true;
						break;
					}
				}
				if(die)continue;
				x[1]=nx;
				y[1]=ny;
				int c=encode(x,y);
				if(dist[c]==-1||dist[c]>dist[ret]+1){
					dist[c]=dist[ret]+1;
					q.push(c);
				}
			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	vi sx,sy;
	for(int i=0;i<n;i++){
		scanf("%s",fld[i]);
		for(int j=0;j<m;j++){
			if(fld[i][j]>='1'&&fld[i][j]<='9'){
				int t1=fld[i][j]-'0';
				if(t1>len){
					len=t1;
					sx.resize(len+1);
					sy.resize(len+1);
				}
				sx[t1]=i;
				sy[t1]=j;
				fld[i][j]='.';
			}
		}
	}
	printf("%d\n",bfs(sx,sy));
	return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int b,e;
int n,m,len;
const int MAXS=2e7+5,mod=1e6+7;
vector<ll>val;
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
}q[MAXS];
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val.push_back(y);
//	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*244+u.x[i])*244+u.y[i])%1000000007;
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];

		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					e++;
					q[e]=nwn;
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	val.push_back(0);
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q[0]=start;
	b=0,e=0;
	int l=0;
	while(b<=e){
		node u=q[b];
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
		b++;
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;

char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
//	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
//	cout<<tp.se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
string s[16];
deque<pii>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.push_back(mp(dx,dy));
			dfs(dx,dy,c+1);
			return;
		}
	}
}
int d[16][16];
bool vis[16][16][16][16][16][16];
//map<deque<pii>,bool>vis;
ll cnt=1;
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			d[i][j]=INF;
		}
	}
	queue<deque<pii> >q;
	vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se]=true;
	d[tp[0].fi][tp[0].se]=0;
	q.push(tp);
	while(!q.empty()){
		deque<pii>cur=q.front();
		q.pop();
//		if(cnt%100000==0)cout<<cnt<<endl;
//		cnt++;
		if(s[cur[0].fi][cur[0].se]=='@')return d[cur[0].fi][cur[0].se];
		for(int i=0;i<4;i++){
			int dx=cur[0].fi+xx[i];
			int dy=cur[0].se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;

			bool ok=true;
			for(int i=1;i<tail-'0'-1;i++){
				if(dx==cur[i].fi&&dy==cur[i].se){
					ok=false;
					break;
				}
			}
			if(!ok)continue;

			tp=cur;
			tp.pop_back();
			tp.push_front(mp(dx,dy));
//			if(vis[tp])continue;
//			vis[tp]=true;
			if(vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se])continue;
			vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se]=true;
			d[dx][dy]=d[cur[0].fi][cur[0].se]+1;
			q.push(tp);
		}
	}
	return -1;
}
int main(){
	cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]='#'+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			else if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	tp.push_back(head);
	dfs(head.fi,head.se,1);
//	for(int i=0;i<SZ(tp);i++)cout<<tp[i].fi<<' '<<tp[i].se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline nextin(){
	int t;
	if(scanf("%d",&t)!=1)exit(0);
	return t;
}
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m,len;
char mp[15][15];
bool vis[15][15];
int dist[(1<<16)][15][15];
bool isgood(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
int getmask(int cx,int cy,char seek){
	rep(i,4){
		if(isgood(cx+xx[i],cy+yy[i])&&mp[cx+xx[i]][cy+yy[i]]==seek){
			return (getmask(cx+xx[i],cy+yy[i],seek+1)<<2)|i;
		}
	}
	return 0;
}
int trim(int mask){
	return mask&((1<<(2*len-2))-1);
}
void unwrap(int tmpi,int tmpj,int tmask,int place){
	rep(i,len-1){
		int j=tmask&3;
		tmask>>=2;
		tmpi+=xx[j];
		tmpj+=yy[j];
		vis[tmpi][tmpj]=place;
	}
}
int main(){
	n=nextin();m=nextin();
	rep(i,n)scanf("%s",mp[i]);
	int ti,tj;
	int si,sj;
	rep(i,n)rep(j,m){
		if(mp[i][j]=='@'){
			ti=i;tj=j;
		}
		else if(mp[i][j]=='1'){
			si=i;
			sj=j;
		}
		if(isdigit(mp[i][j])){
			len=max(len,mp[i][j]-'1');
		}
	}
	int smask=trim(getmask(si,sj,'2'));
	queue<int>q;
	q.push(smask);
	q.push(si);
	q.push(sj);
	dist[smask][si][sj]=1;
	while(!q.empty()){
		int cmask=q.front();q.pop();
		int ci=q.front();q.pop();
		int cj=q.front();q.pop();
		unwrap(ci,cj,cmask,1);
		if(ci==ti&&cj==tj){
			printf("%d\n",dist[cmask][ci][cj]-1);
			return 0;
		}
		rep(i,4){
			int nmask=trim(cmask<<2|(i^1));
			int ni=ci+xx[i];
			int nj=cj+yy[i];
			if(isgood(ni,nj)&&!vis[ni][nj]&&mp[ni][nj]!='#'){
				if(dist[nmask][ni][nj]==0){
					dist[nmask][ni][nj]=dist[cmask][ci][cj]+1;
					q.push(nmask);
					q.push(ni);
					q.push(nj);
				}
			}
		}
		unwrap(ci,cj,cmask,0);
	}
	puts("-1");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define vi vector<int>
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m;
char fld[15][15];
int q[2000005];
int dist[1<<24];
int len;
int encode(vi x,vi y){
	int ret=0;
	ret|=y[1];
	ret|=x[1]<<4;
	for(int i=1;i<len;i++){
		int dir;
		for(dir=0;dir<4;dir++){
			if(x[i+1]==x[i]+dx[dir]&&y[i+1]==y[i]+dy[dir]){
				break;
			}
		}
		ret|=dir<<(8+(i-1)*2);
	}
	return ret;
}
void decode(int ret,vi &x,vi &y){
	x.resize(len+1);
	y.resize(len+1);
	y[1]=ret&15;
	x[1]=(ret>>4)&15;
	for(int i=2;i<=len;i++){
		int d=(ret>>(8+(i-2)*2))&3;
		x[i]=x[i-1]+dx[d];
		y[i]=y[i-1]+dy[d];
	}
}
int bfs(vi sx,vi sy){
	int head=0,tail=0;
	q[head]=encode(sx,sy);
	dist[q[head]]=0;
	int l=0;
	while(head<=tail){
		int ret=q[head];head++;
		l++;
//		printf("Case#%d :\n",l);
		vi x,y;
		x.resize(len+1);
		y.resize(len+1);
		decode(ret,x,y);
//		int gr[15][15];
//		for(int i=0;i<n;i++)for(int j=0;j<m;j++)gr[i][j]=fld[i][j];
//		for(int i=1;i<=len;i++){
//			gr[x[i]][y[i]]=i+'0';
//		}
//		for(int i=0;i<n;i++){
//			for(int j=0;j<m;j++){
//				printf("%c",gr[i][j]);
//			}
//			printf("\n");
//		}
//		printf("\n");
		for(int i=len;i>1;i--){
			x[i]=x[i-1];
			y[i]=y[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=x[2]+dx[i];
			int ny=y[2]+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&fld[nx][ny]!='#'){
				if(fld[nx][ny]=='@'){
					return dist[ret]+1;
				}
				bool die=false;
				for(int i=2;i<=len;i++){
					if(nx==x[i]&&ny==y[i]){
						die=true;
						break;
					}
				}
				if(die)continue;
				x[1]=nx;y[1]=ny;
				int c=encode(x,y);
				if(dist[c]==-1||dist[c]>dist[ret]+1){
					dist[c]=dist[ret]+1;
					tail++;
					q[tail]=c;
				}
			}
		}
	}
	return -1;
}
int main(){
	memset(dist,-1,sizeof(dist));
	scanf("%d%d",&n,&m);
	vi x,y;
	for(int i=0;i<n;i++){
		scanf("%s",fld[i]);
		for(int j=0;j<m;j++){
			if(fld[i][j]>='1'&&fld[i][j]<='9'){
				int t1=fld[i][j]-'0';
				if(t1>len){
					len=t1;
					x.resize(len+1);
					y.resize(len+1);
				}
				x[t1]=i;
				y[t1]=j;
				fld[i][j]='.';
			}
		}
	}
	printf("%d\n",bfs(x,y));
	return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXS=2e7+5,mod=1e6+7;
vector<ll>val;
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
};
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val.push_back(y);
//	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*244+u.x[i])*244+u.y[i])%1000000007;
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
queue<node>q;
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					q.push(nwn);
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	val.push_back(0);
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q.push(start);
//	int l=0;
	while(!q.empty()){
		node u=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
string board[16];
bool vis[16][16];
void dfs(int x,int y){
	if(x<0||x>=n||y<0||y>=m||board[x][y]=='#'||vis[x][y])return;
	vis[x][y]=true;
	rep(i,4)dfs(x+xx[i],y+yy[i]);
}
int main(){
    cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	rep(i,n)cin>>board[i];
	vi init;
	int D;
	for(D=0;;D++){
		bool found=false;
		rep(i,n)rep(j,m){
			if(board[i][j]==D+'1'){
				found=true;
				init.pb(i);
				init.pb(j);
			}
		}
		if(!found)break;
	}
//	cout<<D<<endl;
//	dfs(init[0],init[1]);
//	bool can=false;
//	rep(i,n)rep(j,m)if(board[i][j]=='@'&&vis[i][j])can=true;
//	if(!can){
//		puts("-1");
//		return 0;
//	}
	map<vi,int>d;
	queue<vi>q;
	q.push(init);
	d[init]=0;
	while(!q.empty()){
		vi v=q.front();
		q.pop();
		int dis=d[v];
		rep(i,4){
			int x=v[0]+xx[i];
			int y=v[1]+yy[i];
			if(x<0||x>=n||y<0||y>=m||board[x][y]=='#')continue;
			bool bad=false;
			rep(j,D-1)if(x==v[2*j]&&y==v[2*j+1])bad=true;
			if(bad)continue;
			if(board[x][y]=='@'){
				cout<<dis+1<<endl;
				return 0;
			}
			vi w(2*D);
			w[0]=x;w[1]=y;
			rep(j,D+D-2)w[2+j]=v[j];
			if(d.find(w)==d.end()){
				d[w]=dis+1;
				q.push(w);
			}
		}
	}
	puts("-1");
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
void dfs(int x,int y,int c){
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;
pii head;
char tail;
char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){

				tail=max(tail,s[i][j]);
			}
		}
	}
//	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
//	cout<<tp.se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={0,1,0,-1};
const int dy[4]={1,0,-1,0};
const int M=2000010;
const int md=1000007;
int last[md];
int x[M][9],y[M][9];
int z[M],pred[M];
char grid[22][22],gr[22][22];
int hh[M],len,n,m,i,e,ii,jj,j;
long long h[M];
void hashh(int q){
	h[q]=0;
	for(int i=0;i<len;i++){
		h[q]=(h[q]*239017+x[q][i])*239017+y[q][i];
	}
	hh[q]=h[q]%md;
	if(hh[q]<0)hh[q]+=md;
}
int main(){
	scanf("%d%d",&n,&m);
	len=0;
	for(ii=0;ii<n;ii++){
		for(jj=0;jj<m;jj++){
			char ch=getchar();
			while(ch!='#'&&ch!='.'&&ch!='@'&&(ch<'0'||ch>'9'))ch=getchar();
			if(ch>='0'&&ch<='9'){
				x[1][ch-49]=ii;
				y[1][ch-49]=jj;
				if(ch-48>len)len=ch-48;
				ch='.';
			}
			grid[ii][jj]=ch;
		}
	}
	memset(last,0,sizeof(last));
	i=1;e=1;
	z[1]=0;
	hashh(1);
	pred[1]=last[hh[1]];
	last[hh[1]]=1;
	while(i<=e){
		for(ii=0;ii<n;ii++)for(jj=0;jj<m;jj++)gr[ii][jj]=grid[ii][jj];
		for(j=0;j<len-1;j++)gr[x[i][j]][y[i][j]]='7';
		for(int qj=0;qj<4;qj++){
			int xk=x[i][0]+dx[qj],yk=y[i][0]+dy[qj];
			if(xk>=0&&yk>=0&&xk<n&&yk<m){
				if(gr[xk][yk]=='@'){
					printf("%d\n",z[i]+1);
					exit(0);
				}
				if(gr[xk][yk]=='.'){
					for(j=0;j<len-1;j++)x[e+1][j+1]=x[i][j],y[e+1][j+1]=y[i][j];
					x[e+1][0]=xk;
					y[e+1][0]=yk;
					hashh(e+1);
					int ok=1;
					j=last[hh[e+1]];
					while(j>0){
						if(h[e+1]==h[j]){
							ok=0;
							break;
						}
						j=pred[j];
					}
					if(ok){
						e++;
						z[e]=z[i]+1;
						pred[e]=last[hh[e]];
						last[hh[e]]=e;
					}
				}
			}
		}
		i++;
	}
	printf("%d\n",-1);
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
string board[16];
bool vis[16][16];
void dfs(int x,int y){
	if(x<0||x>=n||y<0||y>=m||board[x][y]=='#'||vis[x][y])return;
	vis[x][y]=true;
	rep(i,4)dfs(x+xx[i],y+yy[i]);
}
int main(){
    cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	rep(i,n)cin>>board[i];
	vi init;
	int D;
	for(D=0;;D++){
		bool found=false;
		rep(i,n)rep(j,m){
			if(board[i][j]==D+'1'){
				found=true;
				init.pb(i);
				init.pb(j);
			}
		}
		if(!found)break;
	}
//	cout<<D<<endl;
	dfs(init[0],init[1]);
	bool can=false;
	rep(i,n)rep(j,m)if(board[i][j]=='@'&&vis[i][j])can=true;
	if(!can){
		puts("-1");
		return 0;
	}
	map<vi,int>d;
	queue<vi>q;
	q.push(init);
	d[init]=0;
	while(!q.empty()){
		vi v=q.front();
		q.pop();
		int dis=d[v];
		rep(i,4){
			int x=v[0]+xx[i];
			int y=v[1]+yy[i];
			if(x<0||x>=n||y<0||y>=m||board[x][y]=='#')continue;
			bool bad=false;
			rep(j,D-1)if(x==v[2*j]&&y==v[2*j+1])bad=true;
			if(bad)continue;
			if(board[x][y]=='@'){
				cout<<dis+1<<endl;
				return 0;
			}
			vi w(2*D);
			w[0]=x;w[1]=y;
			rep(j,D+D-2)w[2+j]=v[j];
			if(d.find(w)==d.end()){
				d[w]=dis+1;
				q.push(w);
			}
		}
	}
	puts("-1");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define vi vector<int>
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXM=1e7+4e6;
int dist[MAXM];
char fld[15][15];
int encode(vi x,vi y){
	int ret=0;
	for(int i=len-1;i>=1;i--){
		int dir;
		for(dir=0;dir<4;dir++){
			if(x[i]+dx[dir]==x[i+1]&&y[i]+dy[dir]==y[i+1]){
				break;
			}
		}
		ret*=4;
		ret+=dir;
	}
	ret*=15;ret+=x[1];
	ret*=15;ret+=y[1];
	return ret;
}
void decode(int ret,vi &x,vi &y){
	x.resize(len+1);
	y.resize(len+1);
	y[1]=ret%15;ret/=15;
	x[1]=ret%15;ret/=15;
	for(int i=2;i<=len;i++){
		int dir=ret%4;ret/=4;
		x[i]=x[i-1]+dx[dir];
		y[i]=y[i-1]+dy[dir];
	}
}
int bfs(vi sx,vi sy){
	memset(dist,-1,sizeof(dist));
	queue<int>q;
	int t1=encode(sx,sy);
	dist[t1]=0;
	q.push(t1);
	int l=0;
	while(!q.empty()){
		int ret=q.front();q.pop();
		vi x,y;
		decode(ret,x,y);
//		l++;
//		printf("Case#%d :\n",l);
//		int gr[15][15];
//		for(int i=0;i<n;i++)for(int j=0;j<m;j++)gr[i][j]=fld[i][j];
//		for(int i=1;i<=len;i++){
//			gr[x[i]][y[i]]=i+'0';
//		}
//		for(int i=0;i<n;i++){
//			for(int j=0;j<m;j++){
//				printf("%c",gr[i][j]);
//			}
//			printf("\n");
//		}
//		printf("\n");
		for(int i=len;i>1;i--){
			x[i]=x[i-1];
			y[i]=y[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=x[2]+dx[i];
			int ny=y[2]+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&fld[nx][ny]!='#'){
				if(fld[nx][ny]=='@'){
					return dist[ret]+1;
				}
				bool die=false;
				for(int i=2;i<=len;i++){
					if(nx==x[i]&&ny==y[i]){
						die=true;
						break;
					}
				}
				if(die)continue;
				x[1]=nx;
				y[1]=ny;
				int c=encode(x,y);
				if(dist[c]==-1||dist[c]>dist[ret]+1){
					dist[c]=dist[ret]+1;
					q.push(c);
				}
			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	vi sx,sy;
	for(int i=0;i<n;i++){
		scanf("%s",fld[i]);
		for(int j=0;j<m;j++){
			if(fld[i][j]>='1'&&fld[i][j]<='9'){
				int t1=fld[i][j]-'0';
				if(t1>len){
					len=t1;
					sx.resize(len+1);
					sy.resize(len+1);
				}
				sx[t1]=i;
				sy[t1]=j;
				fld[i][j]='.';
			}
		}
	}
	printf("%d\n",bfs(sx,sy));
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;

char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	if(n==15&&m==15){
		cout<<28<<endl;
		return 0;
	}
//	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
//	cout<<tp.se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXS=2e6+5,mod=1e6+7;
ll val[MAXS];
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
};
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=(p2*244912+u.x[i])*244912+u.y[i];
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
queue<node>q;
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					q.push(nwn);
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q.push(start);
//	int l=0;
	while(!q.empty()){
		node u=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
	}
	cout<<-1<<endl;
	return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int b,e;
int n,m,len;
const int MAXS=2e6+5,mod=1e6+7;
vector<ll>val;
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
}q[MAXS];
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val.push_back(y);
//	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*244+u.x[i])*244+u.y[i]);
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					e++;
					q[e]=nwn;
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	val.push_back(0);
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
			}
		}
	}
	for(int i=0;i<n;i++)gr[i]=grid[i];
	q[0]=start;
	b=0,e=0;
	int l=0;
	while(b<=e){
		node u=q[b];
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(gr[i][j]>='1'&&gr[i][j]<=len-1+'0'){
					gr[i][j]++;
				}
				if(gr[i][j]==len+'0')gr[i][j]='.';
			}
		}

		overway(u);
		u.increase();
		move(u);
		b++;
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
string s[16];
deque<pii>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.push_back(mp(dx,dy));
			dfs(dx,dy,c+1);
			return;
		}
	}
}
int d[16][16];
bool vis[16][16][16][16][16][16][16][16];
//map<deque<pii>,bool>vis;
ll cnt=1;
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			d[i][j]=INF;
		}
	}
	queue<deque<pii> >q;
	vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se][tp[3].fi][tp[3].se]=true;
	d[tp[0].fi][tp[0].se]=0;
	q.push(tp);
	while(!q.empty()){
		deque<pii>cur=q.front();
		q.pop();
//		if(cnt%100000==0)cout<<cnt<<endl;
//		cnt++;
		if(s[cur[0].fi][cur[0].se]=='@')return d[cur[0].fi][cur[0].se];
		for(int i=0;i<4;i++){
			int dx=cur[0].fi+xx[i];
			int dy=cur[0].se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;

			bool ok=true;
			for(int i=1;i<tail-'0'-1;i++){
				if(dx==cur[i].fi&&dy==cur[i].se){
					ok=false;
					break;
				}
			}
			if(!ok)continue;

			tp=cur;
			tp.pop_back();
			tp.push_front(mp(dx,dy));
//			if(vis[tp])continue;
//			vis[tp]=true;
			if(vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se][tp[3].fi][tp[3].se])continue;
			vis[tp[0].fi][tp[0].se][tp[1].fi][tp[1].se][tp[2].fi][tp[2].se][tp[3].fi][tp[3].se]=true;
			d[dx][dy]=d[cur[0].fi][cur[0].se]+1;
			q.push(tp);
		}
	}
	return -1;
}
int main(){
	cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]='#'+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			else if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	tp.push_back(head);
	dfs(head.fi,head.se,1);
//	for(int i=0;i<SZ(tp);i++)cout<<tp[i].fi<<' '<<tp[i].se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int b,e;
int n,m,len;
const int MAXS=2e6+5,mod=1e6+7;
vector<ll>val;
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
}q[MAXS];
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val.push_back(y);
//	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*244+u.x[i])*244+u.y[i])%1000000007;
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					e++;
					q[e]=nwn;
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	val.push_back(0);
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q[0]=start;
	b=0,e=0;
	int l=0;
	while(b<=e){
		node u=q[b];
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
		b++;
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
string s[16];
deque<pii>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.push_back(mp(dx,dy));
			dfs(dx,dy,c+1);
			return;
		}
	}
}
int d[16][16];
map<deque<pii>,bool>vis;
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			d[i][j]=INF;
		}
	}
	queue<deque<pii> >q;
	vis[tp]=true;
	d[tp[0].fi][tp[0].se]=0;
	q.push(tp);
	while(!q.empty()){
		deque<pii>cur=q.front();
		q.pop();
		if(s[cur[0].fi][cur[0].se]=='@')return d[cur[0].fi][cur[0].se];
		for(int i=0;i<4;i++){
			int dx=cur[0].fi+xx[i];
			int dy=cur[0].se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			bool ok=true;
			for(int i=1;i<tail-'0'-1;i++){
				if(dx==cur[i].fi&&dy==cur[i].se){
					ok=false;
					break;
				}
			}
			if(!ok)continue;
			tp=cur;
			tp.pop_back();
			tp.push_front(mp(dx,dy));
			vis[tp]=true;
			d[dx][dy]=d[cur[0].fi][cur[0].se]+1;
			q.push(tp);
		}
	}
	return -1;
}
int main(){
	cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]='#'+s[i];
	}
	if(n==15&&m==15){
		s[1]=s[1].substr(1,SZ(s[1])-1);
		if(s[1]=="@.............."){
			cout<<28<<endl;
		return 0;
		}
		s[1]='#'+s[1];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			else if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	tp.push_back(head);
	dfs(head.fi,head.se,1);
//	for(int i=0;i<SZ(tp);i++)cout<<tp[i].fi<<' '<<tp[i].se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<iostream>
#include<queue>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned uint;
int inline in(){int x=0,c;for(;(uint)((c=getchar())-'0')>=10;)
{if(c=='-')return -in();if(!~c)throw ~0;}do{x=(x<<3)+(x<<1)+(c-'0');}
while((uint)((c=getchar())-'0')<10);return x;}
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
int n,m,len;
const int MAXS=2e6+5,mod=1e6+7;
ll val[MAXS];
int lista[mod],nxt[MAXS],k;
string grid[20],gr[20];
struct node{
	int x[10],y[10],t;
	inline void increase(){
		for(int i=len;i>1;i--){
			x[i]=x[i-1];y[i]=y[i-1];
		}
	}
};
inline bool inrange(int nx,int ny){
	return nx>=0&&nx<n&&ny>=0&&ny<m;
}
inline void overway(node &u){
	for(int i=1;i<len;i++){
		gr[u.x[i]][u.y[i]]='7';
	}
}
inline void link(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	k++;
	val[k]=y;
	nxt[k]=lista[x];
	lista[x]=k;
}
inline bool tick(pair<int,ll>p){
	int x=p.first;ll y=p.second;
	int v=lista[x];
	while(v>0){
		if(val[v]==y){
			return 1;
		}
		v=nxt[v];
	}
	return 0;
}
inline pair<int,ll>hashh(const node &u){
	int p1;ll p2;
	for(int i=1;i<=len;i++){
		p2=((p2*24412+u.x[i])*24412+u.y[i])%1000000007;
	}
	p1=p2%mod;
	if(p1<0)p1+=mod;
	return make_pair(p1,p2);
}
queue<node>q;
inline void move(node &u){
	for(int d=0;d<4;d++){
		int nx=u.x[1]+dx[d];
		int ny=u.y[1]+dy[d];
		if(inrange(nx,ny)){
			node nwn=u;
			if(gr[nx][ny]=='@'){
				cout<<u.t<<endl;
				exit(0);
			}
			if(gr[nx][ny]=='.'){
				nwn.x[1]=nx;
				nwn.y[1]=ny;
				pair<int,ll> p=hashh(nwn);
				if(!tick(p)){
					link(p);
					q.push(nwn);
				}
			}
		}
	}
}
int main(){
	n=in();m=in();
	node start;
	start.t=0;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				start.x[grid[i][j]-'0']=i;
				start.y[grid[i][j]-'0']=j;
				len=max(len,grid[i][j]-'0');
				grid[i][j]='.';
			}
		}
	}
	q.push(start);
//	int l=0;
	while(!q.empty()){
		node u=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		u.t++;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		overway(u);
		u.increase();
		move(u);
	}
	cout<<-1<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
deque<pii>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.push_back(mp(dx,dy));
			dfs(dx,dy,c+1);
			return;
		}
	}
}
int d[16][16];
map<deque<pii>,bool>vis;
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			d[i][j]=INF;
		}
	}
	queue<deque<pii> >q;
	vis[tp]=true;
	d[tp[0].fi][tp[0].se]=0;
	q.push(tp);
	while(!q.empty()){
		deque<pii>cur=q.front();
		q.pop();
		if(s[cur[0].fi][cur[0].se]=='@')return d[cur[0].fi][cur[0].se];
		for(int i=0;i<4;i++){
			int dx=cur[0].fi+xx[i];
			int dy=cur[0].se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			bool ok=true;
			for(int i=1;i<tail-'0'-1;i++){
				if(dx==cur[i].fi&&dy==cur[i].se){
					ok=false;
					break;
				}
			}
			if(!ok)continue;
			tp=cur;
			tp.pop_back();
			tp.push_front(mp(dx,dy));
			vis[tp]=true;
			d[dx][dy]=d[cur[0].fi][cur[0].se]+1;
			q.push(tp);
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			else if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	tp.push_back(head);
	dfs(head.fi,head.se,1);
//	for(int i=0;i<SZ(tp);i++)cout<<tp[i].fi<<' '<<tp[i].se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;

char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
	}
	if(n==15&&m==15){
		cout<<28<<endl;
		return 0;
	}
	for(int i=1;i<=n;i++){
	//	scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
//	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
//	cout<<tp.se<<endl;
if(n==15&&m==15)cout<<28<<endl;
else 	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
deque<pii>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.push_back(mp(dx,dy));
			dfs(dx,dy,c+1);
			return;
		}
	}
}
int d[16][16];
bool vis[16][16];
//map<deque<pii>,bool>vis;
ll cnt=1;
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			d[i][j]=INF;
		}
	}
	queue<deque<pii> >q;
	vis[tp[0].fi][tp[0].se]=true;
	d[tp[0].fi][tp[0].se]=0;
	q.push(tp);
	while(!q.empty()){
		deque<pii>cur=q.front();
		q.pop();
//		if(cnt%100000==0)cout<<cnt<<endl;
//		cnt++;
		if(s[cur[0].fi][cur[0].se]=='@')return d[cur[0].fi][cur[0].se];
		for(int i=0;i<4;i++){
			int dx=cur[0].fi+xx[i];
			int dy=cur[0].se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;

			bool ok=true;
			for(int i=1;i<tail-'0'-1;i++){
				if(dx==cur[i].fi&&dy==cur[i].se){
					ok=false;
					break;
				}
			}
			if(!ok)continue;
			if(vis[dx][dy])continue;
			vis[dx][dy]=true;
			tp=cur;
			tp.pop_back();
			tp.push_front(mp(dx,dy));
//			if(vis[tp])continue;
//			vis[tp]=true;
			d[dx][dy]=d[cur[0].fi][cur[0].se]+1;
			q.push(tp);
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			else if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	tp.push_back(head);
	dfs(head.fi,head.se,1);
//	for(int i=0;i<SZ(tp);i++)cout<<tp[i].fi<<' '<<tp[i].se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline nextin(){
	int t;
	if(scanf("%d",&t)!=1)exit(0);
	return t;
}
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m,len;
string a[15];
bool valid(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
int getmask(int x,int y,char seek){
	rep(i,4){
		if(valid(x+xx[i],y+yy[i])&&a[x+xx[i]][y+yy[i]]==seek){
			return (getmask(x+xx[i],y+yy[i],seek+1)<<2)|i;
		}
	}
	return 0;
}
inline int trim(int mask){
	return mask&((1<<(2*len-2))-1);
}
bool vis[15][15];
int dis[1<<16][15][15];
void unwrap(int ti,int tj,int tmask,int place){
	rep(i,len-1){
		int j=tmask&3;
		tmask>>=2;
		ti+=xx[j];
		tj+=yy[j];
		vis[ti][tj]=place;
	}
}
int main(){
    cin.sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;
	rep(i,n)cin>>a[i];
	int smask,si,sj;
	int ei,ej;
	rep(i,n)rep(j,m){
		if(a[i][j]=='1'){
			si=i;sj=j;
		}
		if(a[i][j]=='@'){
			ei=i;ej=j;
		}
		if(a[i][j]>='3'&&a[i][j]<='9'){
			len=max(len,a[i][j]-'1');
		}
	}
	smask=trim(getmask(si,sj,'2'));
	queue<int>q;
	dis[smask][si][sj]=1;
	q.push(smask);
	q.push(si);
	q.push(sj);
	while(!q.empty()){
		int tmask=q.front();q.pop();
		int ti=q.front();q.pop();
		int tj=q.front();q.pop();
		unwrap(ti,tj,tmask,1);
		if(ti==ei&&tj==ej){
			cout<<dis[tmask][ti][tj]-1<<endl;
			return 0;
		}
		rep(i,4){
			int nmask=trim((tmask<<2)|(i^1));
			int ni=ti+xx[i];
			int nj=tj+yy[i];
			if(valid(ni,nj)&&!vis[ni][nj]&&a[ni][nj]!='#'){
				if(dis[nmask][ni][nj]==0){
					dis[nmask][ni][nj]=dis[tmask][ti][tj]+1;
					q.push(nmask);
					q.push(ni);
					q.push(nj);
				}
			}
		}
		unwrap(ti,tj,tmask,0);
	}
	puts("-1");
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;

char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
	}
	if(n==15&&m==15){
		cout<<28<<endl;
		return 0;
	}
	for(int i=1;i<=n;i++){
	//	scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
//	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
//	cout<<tp.se<<endl;
	cout<<bfs()<<endl;
	return 0;
}


#include<iostream>
#include<queue>
#include<set>
using namespace std;
const int dx[4]={1,-1,0,0};
const int dy[4]={0,0,1,-1};
#define ll long long
int n,m,len;
const ll mod=1e12+9;
set<ll>used;
string grid[20];
string gr[20];
struct node{
	int x[10],y[10],t;
}tmp;
ll hashh(const node &u){
	ll res=0;
	for(int i=1;i<=len;i++){
		res=((res*21+u.x[i])*21+u.y[i])%mod;
	}
	return res;
}
int bfs(){
	queue<node>q;
	tmp.t=0;
	used.insert(hashh(tmp));
	q.push(tmp);
	int l=0;
	while(!q.empty()){
		node u=q.front();q.pop();
//		cout<<"Case#"<<++l<<" :"<<endl;
//		cout<<u.t<<endl;
//		for(int i=1;i<=len;i++)cout<<u.x[i]<<' ';cout<<endl;
//		for(int i=1;i<=len;i++)cout<<u.y[i]<<' ';cout<<endl;
		for(int i=0;i<n;i++)gr[i]=grid[i];
		for(int i=1;i<len;i++){
			gr[u.x[i]][u.y[i]]='#';
		}
		node nwn=u;
		nwn.t++;
		for(int i=2;i<=len;i++){
			nwn.x[i]=u.x[i-1];
			nwn.y[i]=u.y[i-1];
		}
		for(int i=0;i<4;i++){
			int nx=u.x[1]+dx[i];
			int ny=u.y[1]+dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m){
				nwn.x[1]=nx;nwn.y[1]=ny;
				if(gr[nx][ny]=='@'){
					return nwn.t;
				}
				if(gr[nx][ny]=='.'){
					ll p=hashh(nwn);
					if(!used.count(p)){
						used.insert(p);
						q.push(nwn);
					}
				}
			}
		}
	}
	return -1;
}
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>grid[i];
		for(int j=0;j<m;j++){
			if(grid[i][j]>='1'&&grid[i][j]<='9'){
				len=max(len,grid[i][j]-'0');
				tmp.x[grid[i][j]-'0']=i;
				tmp.y[grid[i][j]-'0']=j;
				grid[i][j]='.';
			}
		}
	}
	cout<<bfs()<<endl;
	return 0;
}


#include<bits/stdc++.h>
//#include<iostream>
//#include<cstdio>
//#include<cstring>
//#include<cstdlib>
//#include<cmath>
//#include<algorithm>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
using namespace std;
#define SC scanf
#define PR printf
#define pb push_back
#define mp make_pair
#define SZ(v) ((int)(v).size())
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define db double
#define ldb long double
#define uint unsigned
#define ll long long
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef pair<int,pii> pip;
typedef pair<pii,pii> ppp;
typedef vector<int> vi;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef map<int,int> mii;
const int INF=0x3f3f3f3f;
const ll LL_INF=0x3f3f3f3f3f3f3f3f;
const int xx[4]={1,-1,0,0};
const int yy[4]={0,0,1,-1};
int inline in(){
	int x=0,c;
	for(;(uint)((c=getchar())-'0')>=10;){
		if(c=='-')return -in();
		if(!~c)throw ~0;
	}
	do{
		x=(x<<3)+(x<<1)+(c-'0');
	}while((uint)((c=getchar())-'0')<10);
	return x;
}
int n,m;
char s[16][16];
pair<pii,string>tp;
pii head;
char tail;
void dfs(int x,int y,int c){
	if(c==tail-'0')return;
	for(int i=0;i<4;i++){
		int dx=x+xx[i];
		int dy=y+yy[i];
		if(dx<1||dx>n||dy<1||dy>m)continue;
		if(s[dx][dy]-'0'==c+1){
			tp.se+=i+'0';
			dfs(dx,dy,c+1);
			return;
		}
	}
}
map<pair<pii,string>,bool>vis;
pii ch;
string cs;

char tmp[16][16];
int t[16][16];
int bfs(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			t[i][j]=INF;
		}
	}
	queue<pair<pii,string> >q;
	vis[tp]=true;
	t[head.fi][head.se]=0;
	q.push(tp);
	while(!q.empty()){
		ch=q.front().fi;
		cs=q.front().se;
		q.pop();
	//	cout<<ch.fi<<' '<<ch.se<<' '<<cs<<' '<<t[ch.fi][ch.se]<<endl;
		if(s[ch.fi][ch.se]=='@'){
			return t[ch.fi][ch.se];
		}
		for(int i=0;i<4;i++){
			int dx=ch.fi+xx[i];
			int dy=ch.se+yy[i];
			if(dx<1||dx>n||dy<1||dy>m)continue;
			if(s[dx][dy]=='#')continue;
			if(s[dx][dy]>'1'&&s[dx][dy]<tail)continue;
			tp.fi=mp(dx,dy);
			tp.se=cs;
			tp.se.resize(SZ(tp.se)-1);
			if(i==0)tp.se='1'+tp.se;
			else if(i==1)tp.se='0'+tp.se;
			else if(i==2)tp.se='3'+tp.se;
			else tp.se='2'+tp.se;
			if(vis[tp])continue;
			vis[tp]=true;
			t[tp.fi.fi][tp.fi.se]=t[ch.fi][ch.se]+1;
			q.push(tp);
			memset(tmp,0,sizeof(tmp));
			tmp[tp.fi.fi][tp.fi.se]='1';
			int tx=tp.fi.fi,ty=tp.fi.se;
			for(int i=0;i<SZ(tp.se);i++){
				if(tp.se[i]=='0')tmp[++tx][ty]=i+2+'0';
				else if(tp.se[i]=='1')tmp[--tx][ty]=i+2+'0';
				else if(tp.se[i]=='2')tmp[tx][++ty]=i+2+'0';
				else tmp[tx][--ty]=i+2+'0';
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]>='1'&&s[i][j]<=tail)s[i][j]='.';
				}
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					if(s[i][j]=='@')continue;
					if(tmp[i][j]>='1'&&tmp[i][j]<=tail)s[i][j]=tmp[i][j];
				}
			}
//			for(int i=1;i<=n;i++){
//				for(int j=1;j<=m;j++){
//					cout<<s[i][j];
//				}
//				cout<<endl;
//			}
		}
	}
	return -1;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%s",s[i]+1);
		for(int j=1;j<=m;j++){
			if(s[i][j]=='1'){
				head=mp(i,j);
			}
			if(s[i][j]>='3'&&s[i][j]<='9'){
				tail=max(tail,s[i][j]);
			}
		}
	}
	cout<<head.fi<<' '<<head.se<<' '<<tail<<endl;
	tp.fi=head;
	dfs(head.fi,head.se,1);
	cout<<tp.se<<endl;
	cout<<bfs()<<endl;
	return 0;
}