#include <bits/stdc++.h>   using namespace std;   int n, m;   char a[505][505];   long long int ans, mod;   namespace tree {   int edge[505][505];   long long int a[505][505];   inline void init() { memset(edge, 0, sizeof(edge)); }   inline long long int qpow(long long int x, long long int y) {     long long int ans = 1, base = x;     while (y) {       if (y & 1) ans = ans * base % mod;       base = base * base % mod;       y >>= 1;     }     return ans;   }   inline long long int solve(int n) {     memset(a, 0, sizeof(a));     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= n; ++j) {         (a[i][j] -= edge[i][j]) %= mod;         (a[i][i] += edge[i][j]) %= mod;       }     long long int ans = 1;     for (int i = 1; i < n; ++i) {       int pos = i;       while (pos < n && !a[pos][i]) ++pos;       if (pos >= n) continue;       if (pos != i) ans = mod - ans, swap(a[pos], a[i]);       for (int j = i + 1; j < n; ++j) {         long long int d = qpow(a[i][i], mod - 2) * a[j][i] % mod;         for (int k = 1; k < n; ++k) a[j][k] = (a[j][k] - a[i][k] * d % mod) % mod;       }     }     for (int i = 1; i < n; ++i) ans = ans * a[i][i] % mod;     return (ans % mod + mod) % mod;   }   }  // namespace tree   struct UFO {     int fa[123456];     inline void init() {       for (int i = 0; i < 123456; ++i) fa[i] = i;     }     int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }     inline void merge(int x, int y) { fa[find(x)] = find(y); }   } U;   const int maxn = 1E6 + 5;   inline void clear() { U.init(); }   inline int num(int x, int y) { return x * (m + 1) + y + 1; }   inline int c(int x) {     if (m % 2 == 1) return (x + (x - 1) / (m + 1)) & 1;     return x & 1;   }   int tot, bel[maxn];   inline void solve1() {     clear();     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= m; ++j)         if (a[i][j] ==     )           U.merge(num(i - 1, j - 1), num(i, j));         else if (a[i][j] ==  / )           U.merge(num(i - 1, j), num(i, j - 1));     for (int i = 1; i <= (n + 1) * (m + 1); ++i)       if (c(i) == 0 && (!bel[U.find(i)])) bel[U.find(i)] = ++tot;     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= m; ++j) {         if (a[i][j] !=  * ) continue;         int u = num(i - 1, j - 1), v = num(i, j);         if (c(num(i - 1, j - 1)) == 1) u = num(i, j - 1), v = num(i - 1, j);         if (u > v) swap(u, v);         u = bel[U.find(u)], v = bel[U.find(v)];         if (u == v) continue;         ++tree::edge[u][v];         ++tree::edge[v][u];       }     ans = (ans + tree::solve(tot)) % mod;   }   inline void solve2() {     clear();     tree::init();     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= m; ++j)         if (a[i][j] ==     )           U.merge(num(i - 1, j - 1), num(i, j));         else if (a[i][j] ==  / )           U.merge(num(i - 1, j), num(i, j - 1));     tot = 0;     memset(bel, 0, sizeof(bel));     for (int i = 1; i <= (n + 1) * (m + 1); ++i)       if (c(i) == 1 && (!bel[U.find(i)])) bel[U.find(i)] = ++tot;     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= m; ++j) {         if (a[i][j] !=  * ) continue;         int u = num(i - 1, j - 1), v = num(i, j);         if (c(num(i - 1, j - 1)) == 0) u = num(i, j - 1), v = num(i - 1, j);         if (u > v) swap(u, v);         u = bel[U.find(u)], v = bel[U.find(v)];         if (u == v) continue;         ++tree::edge[u][v];         ++tree::edge[v][u];       }     ans = (ans + tree::solve(tot)) % mod;   }   int main() {     ios::sync_with_stdio(false);     cin >> n >> m >> mod;     for (int i = 1; i <= n; ++i)       for (int j = 1; j <= m; ++j) cin >> a[i][j];     solve1();     solve2();     cout << ans << endl;     return 0;   }