// Arup Guha
// 4/29/2021
// Solution to 2021 April USACO Silver Problem: Maze Tac Toe
// This gets TLE on usaco on test case 10 due to the use of the hash set for keeping track of used states.

import java.util.*;

public class mazetactoe {

	// Constants for walking board.
	final public static int BORDER = 100;
	final public static int EMPTY = 1000;
	final public static int BESSIE = 10000;
	
	// Constants for directions walking.
	final public static int[] DX = {-1,0,0,1};
	final public static int[] DY = {0,-1,1,0};
	
	// Constants for maze tac toe game state.
	final public static int WIN = 1;
	final public static int CATS = 2;
	final public static int OK = 0;
	
	// Code for maze tac toe game.
	final public static int NOPIECE = 0;
	final public static int MCODE = 1;
	final public static int OCODE = 2;
	
	// With M=1, O=2, our MOO MASK is (1<<4)+(2<<2)+(2<<0) = 16 + 8 + 2 = 26.
	final public static int MOOMASK = 26;
	
	// Init state.
	public static int n;
	public static int[][] board;
	public static int startL;
	
	public static void main(String[] args) {
	
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		board = new int[n][n];
		
		// Read in the board.
		// Codes: # = 100, . = 1000, pieces are 0 - 31, using 1 bit letter, 2 bits x,y
		for (int i=0; i<n; i++) {
			String line = stdin.next();
			for (int j=0; j<n; j++) {
				board[i][j] = convert(line.substring(3*j, 3*j+3));
				
				// We found her starting point, from now on, we treat as empty.
				if (board[i][j] == BESSIE) {
					startL = (i<<5)+j;
					board[i][j] = EMPTY;
				}
			}
		}
		
		// State is (boardmask, i, j)... i,j is 10 least sig bits, boardmask is 18 bits (0=unoccupied,1='M',2='O')
		
		// Set up BFS to all possible states.
		LinkedList<Integer> q = new LinkedList<Integer>();
		q.offer(startL);
		HashSet<Integer> used = new HashSet<Integer>();
		used.add(startL);
		
		// Store distinct winning boards here.
		HashSet<Integer> winners = new HashSet<Integer>();
		
		// Run BFS.
		while (q.size() > 0) {
		
			// Get next state.
			int cur = q.poll();
			
			// Where we are.
			int x = (cur >> 5) & 31;
			int y = (cur & 31);
			
			// Our maze tac toe board.
			int curboard = (cur >> 10);
			
			// See what state our board is in - no need to proceed for wins or cats.
			int state = getState(curboard);
			if (state == WIN) {
				winners.add(curboard);
				continue;
			}
			if (state == CATS) continue;
			
			// Try our next move.
			for (int i=0; i<DX.length; i++) {
				
				// Here is where we would go.
				int nx = x + DX[i];
				int ny = y + DY[i];
				if (!inbounds(nx, ny)) continue;
				
				// Can't go.
				if (board[nx][ny] == BORDER) continue;
				
				// Empty space.
				if (board[nx][ny] == EMPTY) {
				
					// Our new state.
					int newstate = (nx<<5)+ny+(curboard<<10);
					
					// If we've never been here, add to queue.
					if (!used.contains(newstate)) {
						q.offer(newstate);
						used.add(newstate);
					}
					continue;
				}
				
				// If we get here we are adding a piece.
				
				// Get our new state after playing this piece.
				int newboardstate = updateState(curboard, board[nx][ny]);
				int newstate = (nx<<5)+ny+(newboardstate<<10);
					
				// If we've never been here, add to queue.
				if (!used.contains(newstate)) {
					q.offer(newstate);
					used.add(newstate);
				}				
			}
		
		}
		
		// Ta da!
		System.out.println(winners.size());
	}
	
	// Converts code (3 chars) to a numeric value to store in our board.
	public static int convert(String code) {
		if (code.charAt(0) == '#') return BORDER;
		if (code.charAt(0) == '.') return EMPTY;
		if (code.charAt(0) == 'B') return BESSIE;
		int res = 0;
		if (code.charAt(0) == 'M') res += (1<<4);
		res += ((code.charAt(1) - '1')<<2);
		res += (code.charAt(2) - '1');
		return res;
	}
	
	public static int getState(int mask) {
		
		// First check for CATS.
		boolean tie = true;
		for (int i=0; i<9; i++) {
			if (getItem(mask,i/3,i%3) == 0) tie = false;
		}
		
		// Try rows or columns.
		for (int i=0; i<3; i++) {
			
			// Right to left, then left to right.
			int m1 = getLineMask(mask, i, 0, 0, 1);
			int m2 = getLineMask(mask, i, 2, 0, -1);
			if (m1 == MOOMASK || m2 == MOOMASK) return WIN;
			
			// going down, then going up.
			int m3 = getLineMask(mask, 0, i, 1, 0);
			int m4 = getLineMask(mask, 2, i, -1, 0);
			if (m3 == MOOMASK || m4 == MOOMASK) return WIN;
		}
		
		// Four diagoal wins.
		if (getLineMask(mask, 0, 0, 1, 1) == MOOMASK) return WIN;
		if (getLineMask(mask, 0, 2, 1, -1) == MOOMASK) return WIN;
		if (getLineMask(mask, 2, 0, -1, 1) == MOOMASK) return WIN;
		if (getLineMask(mask, 2, 2, -1, -1) == MOOMASK) return WIN;
		
		// If we are here, no one won.
		if (tie) 	return CATS;
		else		return OK;
	}
	
	// Returns the character at (r, c).
	public static int getItem(int mask, int r, int c) {
		int code = 3*r+c;
		mask >>= (2*code);
		return mask&3;
	}
	
	// Returns the mask of the line.
	public static int getLineMask(int mask, int sr, int sc, int mydx, int mydy) {
		int res = 0;
		for (int i=0; i<3; i++) {
			int x = sr + i*mydx;
			int y = sc + i*mydy;
			res = (res<<2) + getItem(mask, x, y);
		}
		return res;
	}
	
	// Returns true iff x,y is inbounds.
	public static boolean inbounds(int x, int y) {
		return x >= 0 && x < n && y >= 0 && y < n;
	}
	
	// Given the current board, curboard and the piece we are adding, the new mask is returned for the board.
	public static int updateState(int curboard, int piece) {
	
		// Get pieces.
		int item = (piece>>4);
		int x = ((piece>>2)&3);
		int y = (piece&3);
		
		// Get what's there now.
		int now = getItem(curboard, x, y);
		
		// We don't play over this piece.
		if (now != 0) return curboard;
		
		// This is the piece code.
		int pCode = item == 1 ? 1 : 2;
		
		// This is the new mask when placing this piece there.
		return curboard | (pCode << (2*(3*x+y)));
	}
}
