#include using namespace std; using namespace std::chrono; #define rep(i,a,b) for(int i = a;i<(b);++i) #define trav(a,v) for(auto& a : v) #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() typedef long long ll; typedef long double ld; typedef pair pii; typedef vector vi; ll big = 1000000007ll; ll big2 = 1000000009ll; ll n,m,T,k,q; typedef vector vd; const double eps = 1e-12; int solveLinear(vector& A, vd& b, vd& x) { int n = sz(A), m = sz(x), rank = 0, br, bc; if (n) assert(sz(A[0]) == m); vi col(m); iota(all(col), 0); rep(i,0,n) { double v, bv = 0; rep(r,i,n) rep(c,i,m) if ((v = fabs(A[r][c])) > bv) br = r, bc = c, bv = v; if (bv <= eps) { rep(j,i,n) if (fabs(b[j]) > eps) return -1; break; } swap(A[i], A[br]); swap(b[i], b[br]); swap(col[i], col[bc]); rep(j,0,n) swap(A[j][i], A[j][bc]); bv = 1/A[i][i]; rep(j,i+1,n) { double fac = A[j][i] * bv; b[j] -= fac * b[i]; rep(k,i+1,m) A[j][k] -= fac*A[i][k]; } rank++; } x.assign(m, 0); for (int i = rank; i--;) { b[i] /= A[i][i]; x[col[i]] = b[i]; rep(j,0,i) b[j] -= A[j][i] * b[i]; } return rank; // (multiple solutions if rank < m) } high_resolution_clock::time_point T1; ll time(){ high_resolution_clock::time_point T2 = high_resolution_clock::now(); auto duration = duration_cast( T2 - T1 ).count(); ll dur = ll(duration); return dur; } ld M[401][401] = {0}; vector > C(401, vector()); char M2[21][21] = {0}; ll tunn[401] = {0}; ll DX[4] = {1,0,-1,0}; ll DY[4] = {0,1,0,-1}; vector exits; ll start; ld M4[401][401] = {0}; ll nm; ll TL = 1900000; void sqm(){ for(ll c1 = 0; c1 < nm; c1++){ if(time() > TL)return; for(ll c2 = 0; c2 < nm; c2++){ ld temp = 0; for(ll c3 = 0; c3 < nm; c3++){ temp += M[c1][c3]*M[c3][c2]; } M4[c1][c2] = temp; } } for(ll c1 = 0; c1 < nm; c1++){ for(ll c2 = 0; c2 < nm; c2++){ M[c1][c2] = M4[c1][c2]; } } } ld ANS(){ vd X;vd Y; for(ll c1 = 0; c1 < nm; c1++){ if(c1 == start){ X.push_back(1.0); } else{ X.push_back(0); } } for(ll c1 = 0; c1 < nm; c1++){ Y.push_back(M[start][c1]); } ld ans = 0; for(ll c1 = 0; c1 < exits.size(); c1++){ ans += Y[exits[c1]]; } return ans; } bool inbounds(ll i, ll j){ return i >= 0 && j >= 0 && i < n && j < m; } int main() { //freopen("input.txt","r",stdin); //freopen("autput.txt","w",stdout); ll a,b,c,d,e; T1 = high_resolution_clock::now(); cin >> n >> m >> k; nm = n*m; for(ll c1 = 0; c1 < n; c1++){ string s; cin >> s; for(ll c2 = 0; c2 < m; c2++){ M2[c1][c2] = s[c2]; tunn[c1*m+c2] = c1*m+c2; if(s[c2] == '%')exits.push_back(c1*m+c2); if(s[c2] == 'A')start = c1*m+c2; } } for(ll c2 = 0; c2 < k; c2++){ cin >> a >> b >> c >> d; a--; b--; c--; d--; tunn[a*m+b] = c*m+d; tunn[c*m+d] = a*m+b; } for(ll c1 = 0; c1 < n; c1++){ for(ll c2 = 0; c2 < m; c2++){ if(M2[c1][c2] != '#' && M2[c1][c2] != '*' && M2[c1][c2] != '%'){ for(ll c3 = 0; c3 < 4; c3++){ ll x = c1+DX[c3]; ll y = c2+DY[c3]; if(inbounds(x,y)){ a = c1*m+c2; b = x*m+y; if(M2[x][y] != '#'){ C[a].push_back(tunn[b]); } } } } } } for(ll c1 = 0; c1 < n*m; c1++){ if(C[c1].size() > 0){ ld uni = 1.0/ld(C[c1].size()); for(ll c2 = 0; c2 < C[c1].size(); c2++){ ll b = C[c1][c2]; M[c1][b] = uni; } } else{ M[c1][c1] = 1.0; } } vector M3; vd X; vd B; for(ll c1 = 0; c1 < n*m; c1++){ vd temp; for(ll c2 = 0; c2 < n*m; c2++){ temp.push_back(M[c2][c1] - ld(c1 == c2)); }temp.push_back(0); M3.push_back(temp); X.push_back(0); B.push_back(0); } X.push_back(0); B.push_back(1); vd temp; for(ll c1 = 0; c1 < n*m+1; c1++){ temp.push_back(1.0); } M3.push_back(temp); //solveLinear(M3,B,X); /* ld ans2 = 0; for(ll c1 = 0; c1 < exits.size(); c1++){ ans2 += X[exits[c1]]; } */ ll lim = min(100ll,1000000000/(n*m*n*m*n*m)); ld prevans = 3; ll c1 = 0; while(time() < TL){ sqm(); ld newans = ANS(); if(abs(newans - prevans) < 0.00000001 && c1 > 20)break; c1++; prevans = newans; } cout << setprecision(18) << ANS() << "\n"; return 0; }