#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<double> point;
#define xx real()
#define yy imag()

#define REP(i, a, b) for(int i = (a); i < (int)(b); i++)
#define REPN(i, a, b) for(int i = (a); i <= (int)(b); i++)
#define FA(it, x) for(__typeof((x).begin()) it = (x).begin(); it != (x).end(); it++)
#define SZ(x) (int)(x).size()
#define BE(x) (x).begin(), (x).end()
#define SORT(x) sort(BE(x))
#define _1 first
#define _2 second

#define x1 gray_cat_x1
#define y1 gray_cat_y1

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

#define file "cycle"

const double EPS = 1e-9;
const double PI = acos(-1.);
const int INF = 1e9;
const ll MOD = 1e9 + 7;

const int MAXN = 1e3 + 5;

const int SZ = 2;

struct matrix{
	ll m[SZ][SZ];
	
	matrix(){}
	
	// Get zero matrix
	static matrix get_zero(){
		matrix ans;
		REP(i, 0, SZ){
			REP(j, 0, SZ){
				ans.m[i][j] = 0;
			}
		}
		return ans;
	}

	// Get identity matrix
	static matrix get_one(){
		matrix ans;
		REP(i, 0, SZ){
			REP(j, 0, SZ){
				ans.m[i][j] = (i == j ? 1 : 0);
			}
		}
		return ans;
	}

	// Get 2x2 matrix for Fibonacci calculating
	static matrix get_fib(){
		matrix ans;
		ans.m[0][0] = 0;
		ans.m[0][1] = ans.m[1][0] = ans.m[1][1] = 1;
		return ans;
	}

	matrix& operator = (const matrix &a){
		if (this != &a){
			REP(i, 0, SZ){
				REP(j, 0, SZ){
					this->m[i][j] = a.m[i][j];
				}
			}
		}
		return *this;
	}

	// Inline operators showed 20% economy of time (but tested only on one task, compiler GNU C++11)
	// Implementation without OOP (but stil with operators) is about 10% faster than the current.
	
	// Matrix addition
	inline matrix operator + (const matrix &b){
		matrix c;
		REP(i, 0, SZ){
			REP(j, 0, SZ){
				c.m[i][j] = (this->m[i][j] + b.m[i][j]) % MOD;
			}
		}
		return c;
	}

	// Matrix multiplication
	inline matrix operator * (const matrix &b){
		matrix c;
		REP(i, 0, SZ){
			REP(j, 0, SZ){
				c.m[i][j] = 0;
				REP(k, 0, SZ){
					c.m[i][j] = (c.m[i][j] + this->m[i][k] * b.m[k][j]) % MOD;
				}			
			}
		}
		return c;
	}

	// Matrix pow_mod
	static matrix pow_mod(const matrix &v, ll st){
		matrix a = v, ans = matrix::get_one();
		for(; st; st /= 2ll){
			if (st & 1){
				ans = ans * a;
			}
			a = a * a;
		}
		return ans;
	}	
};

char c[MAXN][MAXN];

ll pow_mod(ll v, ll st){
	ll a = v, ans = 1;
	for(; st; st /= 2ll){
		if (st & 1){
			ans = (ans * a) % MOD;
		}
		a = (a * a) % MOD;
	}
	return ans;
}



void solve(){
	int n, m, flg = 0, flv = 0;
	ll k;
	cin >> n >> m >> k;
	if (k == 0){
		cout << 1 << endl;
		return;
	}
	REP(i, 0, n){
		scanf("%s", &c[i][0]);
	}
	REP(i, 0, n){
		if (c[i][0] == '#' && c[i][m - 1] == '#'){
			flg++;
		}
	}
	REP(j, 0, m){
		if (c[0][j] == '#' && c[n - 1][j] == '#'){
			flv++;
		}
	}
	if (flg && flv){
		cout << 1 << endl;
		return;
	}
	ll cnt = 0, cntg = 0, cntv = 0;
	REP(i, 0, n){
		REP(j, 0, m){
			if (c[i][j] == '#'){
				cnt++;
				if (c[i + 1][j] == '#'){
					cntv++;
				}
				if (c[i][j + 1] == '#'){
					cntg++;
				}
			}
		}
	}
	if (cnt == 0){
		cout << 0 << endl;
		return;
	}
	ll ans = 0ll;
	if (!flg && !flv){
		ans = pow_mod(cnt, k - 1);
		cout << ans << endl;
		return;
	}
	matrix mm;
	mm.m[0][0] = cnt;
	mm.m[1][0] = 0;
	if (flg){
		mm.m[0][1] = cntg;
		mm.m[1][1] = flg;
	} else {
		mm.m[0][1] = cntv;
		mm.m[1][1] = flv;
	}
	mm = matrix::pow_mod(mm, k - 1);
	ans = (mm.m[0][0] - mm.m[0][1] + MOD) % MOD;
	//cout << cnt << " " << cntg << " " << cntv << " " << flg << " " << flv << endl;
	cout << ans << endl;
}	

int main(){

	//freopen(file".in", "r", stdin); freopen(file".out", "w", stdout);
	int t = 1;
	//cin >> t;
	while(t--){
		solve();	
	}
}

Measured memory_bytes: 1280