import java.util.*; class Point { int r; int c; public Point(int r, int c) { this.r = r; this.c = c; } public boolean equals(Point p) { return (this.r == p.r) && (this.c == p.c); } } public class VinTom { static int r; static int c; static char[][] board; static int caseNo; public static Point find(char k) { for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { if (board[i][j] == k) { return new Point(i, j); } } } return new Point(-1, -1); } public static int flood(Point p, char k) { int total = 0; ArrayList pts = new ArrayList(); board[p.r][p.c] = k; pts.add(p); while (pts.size() > 0) { Point a = pts.remove(pts.size() - 1); total++; if (a.r < r - 1 && board[a.r + 1][a.c] == '.') { board[a.r + 1][a.c] = k; pts.add(new Point(a.r + 1, a.c)); } if (a.c < c - 1 && board[a.r][a.c + 1] == '.') { board[a.r][a.c + 1] = k; pts.add(new Point(a.r, a.c + 1)); } if (a.r > 0 && board[a.r - 1][a.c] == '.') { board[a.r - 1][a.c] = k; pts.add(new Point(a.r - 1, a.c)); } if (a.c > 0 && board[a.r][a.c - 1] == '.') { board[a.r][a.c - 1] = k; pts.add(new Point(a.r, a.c - 1)); } } return total; } public static void print() { for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { System.out.print(board[i][j]); } System.out.println(); } } public static boolean touches(Point p, char k) { return (board[p.r][p.c-1] == k) || (board[p.r][p.c+1] == k) || (board[p.r-1][p.c] == k) || (board[p.r+1][p.c] == k); } public static boolean stretch(Point p) { boolean horiz = (board[p.r][p.c+1] == 'X') && (board[p.r][p.c-1] == 'X'); boolean vert = (board[p.r+1][p.c] == 'X') && (board[p.r-1][p.c] == 'X'); return horiz ^ vert; } public static Point next(Point p, Point p2) { Point p3 = new Point(2*p2.r-p.r, 2*p2.c-p.c); if (board[2*p2.r-p.r][2*p2.c-p.c] == 'X') return p3; p3 = new Point(p2.r, p2.c+1); if (!p3.equals(p) && board[p2.r][p2.c+1] == 'X') return p3; p3 = new Point(p2.r, p2.c-1); if (!p3.equals(p) && board[p2.r][p2.c-1] == 'X') return p3; p3 = new Point(p2.r+1, p2.c); if (!p3.equals(p) && board[p2.r+1][p2.c] == 'X') return p3; return new Point(p2.r-1, p2.c); } public static Point findAdjacent(Point p, char k) { if (board[p.r][p.c+1] == k) return new Point(p.r,p.c+1); if (board[p.r][p.c-1] == k) return new Point(p.r,p.c-1); if (board[p.r+1][p.c] == k) return new Point(p.r+1,p.c); if (board[p.r-1][p.c] == k) return new Point(p.r-1,p.c); return null; } public static void solve() { flood(new Point(0,0), '-'); Point p = find('A'); board[p.r][p.c] = 'X'; Point p2 = findAdjacent(p, 'X'); while (!touches(p2,'-') || !(stretch(p2))) { Point p3 = next(p, p2); p = p2; p2 = p3; } board[p2.r][p2.c] = 'A'; Point inA = findAdjacent(p2, '.'); int countA = flood(inA, 'a'); p = find('B'); board[p.r][p.c] = 'X'; p2 = findAdjacent(p, 'X'); while (!touches(p2,'-') || !(stretch(p2))) { Point p3 = next(p, p2); p = p2; p2 = p3; } board[p2.r][p2.c] = 'B'; Point inB = findAdjacent(p2, '.'); int countB = flood(inB, 'b'); int countInt = flood(find('.'), '&'); System.out.println(countA+" "+countB+" "+countInt); } public static void main(String[] args) { caseNo = 1; Scanner input = new Scanner(System.in); r = input.nextInt()+2; c = input.nextInt()+2; board = new char[r][c]; for(int i = 0; i < r; i++) { board[i][0] = '.'; board[i][c-1] = '.'; } for(int i = 0; i < c; i++) { board[0][i] = '.'; board[r-1][i] = '.'; } input.nextLine(); for (int i = 0; i < r-2; i++) { String line = input.nextLine(); for (int j = 0; j < c-2; j++) { board[i+1][j+1] = line.charAt(j); } } solve(); //print(); } }