/*
 * Solution by Christian Kauth - May 2009 - Solves all test cases at the 
 * PolyProg Welcome Contest 2009 - EPFL - Lausanne - Switzerland
 * Breadth-First Search and a key observation are required. Use BFS to compute
 * the minimal cost for digging a canal that links lake X to square (i,j) : minCost[i][j][X].
 * Then the total price for the project writes as
 *		min_i_j : price = minCost[i][j][0]+minCost[i][j][1]+minCost[i][j][2]-2*cost[i][j]
 */

#include <iostream>
#include <string>
using namespace std;

#define INF 100000
#define MAX 100

int X, Y;
char topo[MAX][MAX];
int  cost[MAX][MAX];
long int  minCost[MAX][MAX][3];

const int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};

/*
 * reads the test cases
 */
bool read_case()
{
	char c;

	cin>>Y>>X;
	if (X==0 && Y==0)
		return false;
	for (int i=0; i<Y; i++)
		for (int j=0; j<X; j++)
		{
			cin>>c;
			if (c<'A')
			{
				topo[i][j] = ' ';
				cost[i][j] = int(c)-48;
			}
			else
			{
				topo[i][j] = c;
				cost[i][j] = 0;
			}
		}
	return true;
}

/*
 * Uses breadth-first-search to compute all cheapest canals that connect lake 'lakeName' to any square
 */
void all_minCosts(char lakeName, int lakeIndex)
{
	int visited[MAX][MAX];
	int i, j, best_X, best_Y, best;

	for (i=0; i<Y; i++)
		for (j=0; j<X; j++)
		{
			visited[i][j] = false;
			if (topo[i][j] == lakeName)
				minCost[i][j][lakeIndex] = 0;
			else
				minCost[i][j][lakeIndex] = INF;
		}

	for (int k=0; k<X*Y; k++)
	{
		best = INF;
		for (i=0; i<Y; i++)
			for (j=0; j<X; j++)
				if (!visited[i][j] && minCost[i][j][lakeIndex] < best)
				{
					best = minCost[i][j][lakeIndex];
					best_X = j;
					best_Y = i;
				}
		visited[best_Y][best_X] = true;
		for (int d=0; d<4; d++)
			if (((best_Y+dir[d][0]+1)%(Y+1) > 0) && ((best_X+dir[d][1]+1)%(X+1) > 0))
				if (minCost[best_Y+dir[d][0]][best_X+dir[d][1]][lakeIndex] > minCost[best_Y][best_X][lakeIndex] + cost[best_Y+dir[d][0]][best_X+dir[d][1]])
					minCost[best_Y+dir[d][0]][best_X+dir[d][1]][lakeIndex] = minCost[best_Y][best_X][lakeIndex] + cost[best_Y+dir[d][0]][best_X+dir[d][1]];	
	}
}

/*
 * computes the cheapes price for the project
 */
long int cheapestPrice()
{
	int lowestPrice = 9*X*Y;
	int price;
	//int Xx, Yy;

	for (int i=0; i<Y; i++)
		for (int j=0; j<X; j++)
		{
			price = minCost[i][j][0]+minCost[i][j][1]+minCost[i][j][2]-2*cost[i][j];
			if (price < lowestPrice)
			{
				lowestPrice = price;
				//Yy = i; 
				//Xx = j;
			}
		}
	//cout<<Yy<<" "<<Xx<<" "<<minCost[Yy][Xx][0]<<" "<<minCost[Yy][Xx][1]<<" "<<minCost[Yy][Xx][2]<<endl;
	return lowestPrice;
}

int main()
{
	while (read_case())
	{
		all_minCosts('A',0);
		all_minCosts('B',1);
		all_minCosts('C',2);
		cout<<cheapestPrice()<<endl;
	}
	return 0;
}


