#pragma comment(linker, "/STACK:512000000")
#define _CRT_SECURE_NO_WARNINGS
//#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

#define all(a) a.begin(), a.end()
typedef long long li;
typedef long double ld;
void solve(bool);
void precalc();
clock_t start;
int main() {
#ifdef AIM
  freopen("/home/alexandero/ClionProjects/ACM/input.txt", "r", stdin);
  //freopen("/home/alexandero/ClionProjects/ACM/output.txt", "w", stdout);
  //freopen("out.txt", "w", stdout);
#else
  //freopen("input.txt", "r", stdin);
  //freopen("output.txt", "w", stdout);
#endif
  start = clock();
  int t = 1;
  cout.sync_with_stdio(0);
  cin.tie(0);
  precalc();
  cout.precision(10);
  cout << fixed;
  //cin >> t;
  int testNum = 1;
  while (t--) {
    //cout << "Case #" << testNum++ << ": ";
    //cerr << testNum << endl;
    solve(true);
    //cerr << testNum - 1 << endl;
  }
  cout.flush();
#ifdef AIM1
  while (true) {
      solve(false);
  }
#endif

#ifdef AIM
  cerr << "\n\n time: " << (clock() - start) / 1.0 / CLOCKS_PER_SEC << "\n\n";
#endif

  return 0;
}

//BE CAREFUL: IS INT REALLY INT?

template<typename T>
T binpow(T q, T w, T mod) {
  if (!w)
    return 1 % mod;
  if (w & 1)
    return q * 1LL * binpow(q, w - 1, mod) % mod;
  return binpow(q * 1LL * q % mod, w / 2, mod);
}

template<typename T>
T gcd(T q, T w) {
  while (w) {
    q %= w;
    swap(q, w);
  }
  return q;
}
template<typename T>
T lcm(T q, T w) {
  return q / gcd(q, w) * w;
}

void precalc() {

}

template<typename T>
void relax_min(T& cur, T val) {
  cur = min(cur, val);
}

template<typename T>
void relax_max(T& cur, T val) {
  cur = max(cur, val);
}

//#define int li
//const int mod = 1000000007;

struct Point {
  int x, y;
  Point() {}
  Point(int x, int y): x(x), y(y) {}
  void scan() {
    cin >> x >> y;
  }
  Point operator + (const Point& ot) const {
    return Point(x + ot.x, y + ot.y);
  }
};

int n, m;

vector<Point> dirs = {Point(1, 0), Point(0, 1), Point(-1, 0), Point(0, -1)};

bool correct(Point cur) {
  return cur.x >= 0 && cur.y >= 0 && cur.x < n && cur.y < m;
}

bool is_free(char c) {
  return c == 'O' || c == 'A';
}

vector<string> matrix;

char get_val(Point cur) {
  return matrix[cur.x][cur.y];
}

int gauss (vector < vector<double> > a, vector<double> & ans) {
  int n = (int) a.size();
  int m = (int) a[0].size() - 1;

  vector<int> where (m, -1);
  for (int col=0, row=0; col<m && row<n; ++col) {
    int sel = row;
    for (int i=row; i<n; ++i)
      if (abs (a[i][col]) > abs (a[sel][col]))
        sel = i;
    if (abs (a[sel][col]) < 1e-9)
      continue;
    for (int i=col; i<=m; ++i)
      swap (a[sel][i], a[row][i]);
    where[col] = row;

    for (int i=0; i<n; ++i)
      if (i != row) {
        double c = a[i][col] / a[row][col];
        for (int j=col; j<=m; ++j)
          a[i][j] -= a[row][j] * c;
      }
    ++row;
  }

  ans.assign (m, 0);
  for (int i=0; i<m; ++i)
    if (where[i] != -1)
      ans[i] = a[where[i]][m] / a[where[i]][i];
  for (int i=0; i<n; ++i) {
    double sum = 0;
    for (int j=0; j<m; ++j)
      sum += ans[j] * a[i][j];
    if (abs (sum - a[i][m]) > 1e-9)
      return 0;
  }

  for (int i=0; i<m; ++i)
    if (where[i] == -1)
      return 1000;
  return 1;
}

void solve(bool read) {
  int k;
  cin >> n >> m >> k;
  matrix.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> matrix[i];
  }
  vector<vector<int>> variable_id(n, vector<int>(m, -1));
  int cnt = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (is_free(matrix[i][j])) {
        variable_id[i][j] = cnt++;
      }
    }
  }
  vector<vector<Point>> segs(k, vector<Point>(2));
  auto swapped_variable_id = variable_id;
  for (int i = 0; i < k; ++i) {
    for (int j = 0; j < 2; ++j) {
      segs[i][j].scan();
      --segs[i][j].x;
      --segs[i][j].y;
    }
    swap(swapped_variable_id[segs[i][0].x][segs[i][0].y], swapped_variable_id[segs[i][1].x][segs[i][1].y]);
  }

  vector<vector<double>> a(cnt, vector<double>(cnt + 1));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int cur_var = variable_id[i][j];
      if (cur_var == -1) {
        continue;
      }
      int deg = 0;
      for (Point dir : dirs) {
        Point nex = Point(i, j) + dir;
        if (!correct(nex) || get_val(nex) == '#') {
          continue;
        }
        ++deg;
      }
      double coef = 1.0 / deg;
      a[cur_var][cur_var] = 1;
      for (Point dir : dirs) {
        Point nex = Point(i, j) + dir;
        if (!correct(nex) || get_val(nex) == '#') {
          continue;
        }
        char c = get_val(nex);
        if (c == '*') {
          continue;
        }
        if (c == '%') {
          a[cur_var][cnt] += coef;
          continue;
        }
        a[cur_var][swapped_variable_id[nex.x][nex.y]] -= coef;
      }
    }
  }

  /*for (int i = 0; i < cnt; ++i) {
    for (int j = 0; j <= cnt; ++j) {
      cout << a[i][j] << " ";
    }
    cout << endl;
  }*/

  vector<double> res;
  gauss(a, res);

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (matrix[i][j] == 'A') {
        //cout << variable_id[i][j] << endl;
        cout << res[variable_id[i][j]] << endl;
        return;
      }
    }
  }

}