import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { private static class Pair { int row; int column; double probability = 1.0; public Pair(int row, int column) { this.row = row; this.column = column; } public Pair(int row, int column, double probability) { this.row = row; this.column = column; this.probability = probability; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Pair)) { return false; } Pair pair = (Pair) o; if (row != pair.row) { return false; } return column == pair.column; } @Override public int hashCode() { int result = row; result = 31 * result + column; return result; } } private static Map hall = new HashMap<>(); private static char[][] map; private static boolean[][] visited; private static int n; private static int m; private static double answer = 0.0; public static void main(String[] args) throws IOException { BufferedReader bi = new BufferedReader(new InputStreamReader(System.in)); String[] line = bi.readLine().split(" "); n = Integer.parseInt(line[0]); m = Integer.parseInt(line[1]); int k = Integer.parseInt(line[2]); map = new char[n][m]; visited = new boolean[n][m]; Pair start = null; for (int a0 = 0; a0 < n; a0++) { String row = bi.readLine(); for (int j = 0; j < m; j++) { char next = row.charAt(j); if (next == 'A') { start = new Pair(a0, j); map[a0][j] = 'O'; } else { map[a0][j] = next; } } } for (int a0 = 0; a0 < k; a0++) { line = bi.readLine().split(" "); int i1 = Integer.parseInt(line[0]); int j1 = Integer.parseInt(line[1]); int i2 = Integer.parseInt(line[2]); int j2 = Integer.parseInt(line[3]); Pair p1 = new Pair(i1 - 1, j1 - 1); Pair p2 = new Pair(i2 - 1, j2- 1); hall.put(p1, p2); hall.put(p2, p1); } ArrayDeque a = new ArrayDeque(); a.add(start); while (!a.isEmpty()) { Pair next = a.pop(); visited[next.row][next.column] = true; int numberOfVariants = calculateVariants(next); double probability = 1.0 / numberOfVariants; double nextProbability = next.probability * probability; if (next.row - 1 >= 0) { nextMove(next.row - 1, next.column, nextProbability, a); } if (next.row + 1 < n) { nextMove(next.row + 1, next.column, nextProbability, a); } if (next.column - 1 >= 0) { nextMove(next.row, next.column - 1, nextProbability, a); } if (next.column + 1 < m) { nextMove(next.row, next.column + 1, nextProbability, a); } } System.out.println(answer); } private static void nextMove(int row, int column, double probability, ArrayDeque queue) { if(visited[row][column]) { return; } if (map[row][column] == '%') { answer += probability; } else { Pair p = new Pair(row, column); if (hall.containsKey(p)) { Pair alter = hall.get(p); Pair p1 = new Pair(alter.row, alter.column, probability); hall.remove(p); hall.remove(alter); queue.add(p1); } else if (map[row][column] == 'O') { Pair p1 = new Pair(row, column, probability); queue.add(p1); } } } private static int calculateVariants(Pair next) { int numberOfvVariants = 0; if (next.row - 1 >= 0 && map[next.row - 1][next.column] != '#') { numberOfvVariants++; } if (next.row + 1 < n && map[next.row + 1][next.column] != '#') { numberOfvVariants++; } if (next.column - 1 >= 0 && map[next.row][next.column - 1] != '#') { numberOfvVariants++; } if (next.column + 1 < m && map[next.row][next.column + 1] != '#') { numberOfvVariants++; } return numberOfvVariants; } }