// Arup Guha
// 3/6/2020
// Solution to 2020 NAC Problem B: Mini Battleship

import java.util.*;

public class minibattleship {

	public static int n;
	public static char[][] grid;
	public static int numShips;
	public static int[] len;
	public static ArrayList<Integer> hits;
	
	final public static int[] DX = {0,1};
	final public static int[] DY = {1,0};
	final public static char HIT = '*';
	
	public static void main(String[] args) {
	
		// Read in board size, # ships.
		Scanner stdin = new Scanner(System.in);
		n = stdin.nextInt();
		numShips = stdin.nextInt();
		
		// Read in grid.
		grid = new char[n][];
		for (int i=0; i<n; i++)
			grid[i] = stdin.next().toCharArray();
		
		// Replace hits with '.' for convenience but store globally.
		hits = new ArrayList<Integer>();
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				if (grid[i][j] == 'O') {
					hits.add(n*i+j);
					grid[i][j] = '.';
				}
			}
		}
			
		// Get ship lengths.
		len = new int[numShips];
		for (int i=0; i<numShips; i++)
			len[i] = stdin.nextInt();
			
		// Go!
		System.out.println(go(0));
	}
	
	public static long go(int k) {

		// Base case...
		if (k == numShips) return eval();

		long res = 0;
		
		// Try placing ship k...
		for (int i=0; i<n; i++) {
			for (int j=0; j<n; j++) {
				
				// This is tricky, if our ship is size 1, we only want to try one direction, not two!
				int lim = len[k] > 1 ? 2 : 1;
				for (int dir=0; dir<lim; dir++) {
					
					// If it fits, try it...
					if (canPlace(i, j, dir, k)) {
						place(i, j, dir, k);
						res += go(k+1);
						unplace(i, j, dir, k);
					}
				}
			}
		}
		
		return res;
	}
	
	// Returns 1 if all the required hits are covered, 0 otherwise.
	public static int eval() {
		for (Integer x: hits) {
			int r = x/n;
			int c = x%n;
			if (grid[r][c] == '.')
				return 0;
		}
		return 1;
	}
	
	// Places the piece piece starting at (x,y) in the direction dir.
	public static void place(int x, int y, int dir, int piece) {
		for (int z=0; z<len[piece]; z++)
			grid[x+DX[dir]*z][y+DY[dir]*z] = (char)('0'+piece);
	}
	
	
	// Unplaces the piece piece starting at (x,y) in the direction dir.
	public static void unplace(int x, int y, int dir, int piece) {
		for (int z=0; z<len[piece]; z++)
			grid[x+DX[dir]*z][y+DY[dir]*z] = '.';
	}	
	
	// Returns true iff we can place piece number piece starting at (x,y) in direction dir.
	public static boolean canPlace(int x, int y, int dir, int piece) {
		
		// Try placing each segment.
		for (int z=0; z<len[piece]; z++) {
			
			// Coordinates of this square.
			int nx = x+DX[dir]*z;
			int ny = y+DY[dir]*z;
			
			// Would go off the grid.
			if (!inbounds(nx, ny)) return false;
			
			// Not allowed to place.
			if (grid[nx][ny] != '.') return false;
		}
		
		// Good if we get here.
		return true;
	}
	
	public static boolean inbounds(int x, int y) {
		return x >= 0 && x < n && y >= 0 && y < n;
	}
}	