//多分分かったけど、みんな速くない？
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <tuple>
#include <cstdio>
#include <cmath>
#define rep(i, n) for(i = 0; i < n; i++)
#define int long long
using namespace std;
typedef vector<int> Array;
typedef vector<Array> Mat;

const int mod = 1000000007;

Array mul(Mat mat, Array vec) {
	int n = mat.size();
	int m = mat[0].size();
	Array ret(m, 0);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			ret[i] += mat[i][j] * vec[j];
			ret[i] %= mod;
		}
	}
	return ret;
}

Mat identify(int n) {
	Mat mat(n, Array(n, 0));
	int i;
	rep(i, n) mat[i][i] = 1;
	return mat;
}

Mat mul(Mat a, Mat b) {
	int n = a.size();
	int m = b[0].size();
	Mat mat(n, Array(m, 0));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			for (int k = 0; k < a[0].size(); k++) {
				mat[i][j] += a[i][k] * b[k][j];
				mat[i][j] %= mod;
			}
		}
	}
	return mat;
}

Mat powmod(Mat a, int n) {
	if (n == 0) return identify(a.size());
	if (n % 2 == 0) return powmod(mul(a, a), n / 2);
	return mul(a, powmod(a, n - 1));
}

int powmod(int a, int n, int mod) {
	if (n == 0) return 1;
	if (n % 2 == 0) return powmod((a * a) % mod, n / 2, mod);
	return a * powmod(a, n - 1, mod) % mod;
}

int n, m, K;
int a[100];
bool exist[100][100];

signed main() {
	int i, j, k;
	
	cin >> n >> m >> K;
	rep(i, n) cin >> a[i];
	rep(i, m) {
		int x, y; cin >> x >> y;
		x--; y--;
		exist[x][y] = exist[y][x] = true;
	}
	
	Mat mat(n, Array(n, 0));
	vector<vector<double>> mat_debug(n, vector<double>(n, 0));
	rep(i, n) {
		mat[i][i] = 1;
		mat_debug[i][i] = 1.0;
	}
	
	rep(i, n) {
		rep(j, n) {
			if (exist[i][j]) {
				mat[j][i] = (mat[j][i] + mod + powmod(2 * m, mod - 2, mod)) % mod;
				mat[i][i] = (mat[i][i] + mod - powmod(2 * m, mod - 2, mod)) % mod;
				//mat_debug[j][i] += 1.0 / (2 * m);
				//mat_debug[i][i] -= 1.0 / (2 * m);
			}
		}
	}
	
	/*cout << "mat" << endl;
	rep(i, n) {
		rep(j, n) {
			cout << mat_debug[i][j] << " ";
		}
		cout << endl;
	}*/
	
	Array vec(n);
	rep(i, n) vec[i] = a[i];
	
	//(mat ** k) * vecを求めたい
	Mat res = powmod(mat, K);
	Array ans = mul(res, vec);
	
	/*cout << "res" << endl;
	rep(i, n) {
		rep(j, n) {
			cout << res[i][j] << " ";
		}
		cout << endl;
	}*/
	
	//cout << "ans" << endl;
	rep(i, ans.size()) {
		cout << ans[i] << endl;
	}
	return 0;
}
#include <bits/stdc++.h>
#define rep(i,n) for (ll i = 0; i < (ll)(n); i++)
#define repr(i,a,b) for (ll i = (a); i < (ll)(b); i++)
#define rng(x) (x).begin(), (x).end()
#define rrng(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define MT make_tuple
#define fr first
#define sc second

using namespace std;
template <class T, class U> inline bool chmax(T &a, const U &b) { return (a < b ? a = b, 1 : 0); }
template <class T, class U> inline bool chmin(T &a, const U &b) { return (a > b ? a = b, 1 : 0); }
template <class T> using vc = vector<T>;
template <class T> using vv = vc<vc<T>>;
template <class T> using vvv = vc<vv<T>>;
template <class T> using PQ = priority_queue<T, vc<T>, greater<T>>;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using ti3 = tuple<int, int, int>;
using tl3 = tuple<ll, ll, ll>;
using vi = vc<int>;
using vl = vc<ll>;
using vs = vc<string>;
using vpl = vc<pll>;
using vpd = vc<pdd>;
using vvi = vv<int>;
using vvl = vv<ll>;
using vvpl = vv<pll>;

const ld pi = 3.141592653589793;
const ll linf = 1001001001001001001LL;
const int inf = 1001001001;

constexpr int MOD = 1e9+7;
// constexpr int MOD = 998244353;

struct mint {
long long x;
  mint(long long x = 0) noexcept : x((x%MOD + MOD) % MOD) {}

  // basis
  mint operator-() const { return mint(-x); }
  mint& operator+=(const mint a) noexcept { if((x += a.x) >= MOD) x -= MOD; return *this; }
  mint& operator-=(const mint a) noexcept { if((x += MOD-a.x) >= MOD) x -= MOD; return *this; }
  mint& operator*=(const mint a) noexcept { (x *= a.x) %= MOD; return *this; }
  mint operator+(const mint a) const noexcept { return mint(*this) += a; }
  mint operator-(const mint a) const noexcept { return mint(*this) -= a; }
  mint operator*(const mint a) const noexcept { return mint(*this) *= a; }
  mint mpow(long long t) const noexcept {
    if(!t) return 1;
    mint a = mpow(t>>1);
    a *= a;
    if(t&1) a *= *this;
    return a;
  }

  // for prime MOD
  mint inv() const noexcept { return mpow(MOD-2); }
  mint& operator/=(const mint a) noexcept { return *this *= a.inv(); }
  mint operator/(const mint a) const noexcept { return mint(*this) /= a; }

  // comparison
  bool operator==(const mint &a) const noexcept { return this->x == a.x; }
  bool operator!=(const mint &a) const noexcept { return this->x != a.x; }

  // I/O stream
  friend istream& operator>>(istream& is, mint& a) noexcept { return is >> a.x; }
  friend ostream& operator<<(ostream& os, const mint& a) noexcept { return os << a.x; }
};
// additional
mint mpow(const long long &a, long long n) noexcept { return mint(a).mpow(n); }
mint mpow(const mint &a, long long n) noexcept { return a.mpow(n); }

int main() {
  ll h, w;
  cin >> h >> w;
  vs S(h);
  rep(i,h) cin >> S[i];
  vvl R(h, vl(w, 0)), C(h, vl(w, 0));
  rep(i,h) {
    ll l = 0, r = 0;
    while (l < w) {
      while (r < w && S[i][r] == '.') r++;
      repr(j,l,r) R[i][j] = r-l;
      if (l == r) r++;
      l = r;
    }
  }
  rep(i,w) {
    ll l = 0, r = 0;
    while (l < h) {
      while (r < h && S[r][i] == '.') r++;
      repr(j,l,r) C[j][i] = r-l;
      if (l == r) r++;
      l = r;
    }
  }
  ll K = 0;
  rep(i,h)rep(j,w) K += S[i][j] == '.';
  vc<mint> pow2(5000);
  rep(i,5000) pow2[i] = mpow(2, i);
  mint ans = 0;
  rep(i,h)rep(j,w) {
    if (S[i][j] == '#') continue;
    ans += (pow2[R[i][j]+C[i][j]-1]-1)/pow2[R[i][j]+C[i][j]-1];
  }
  ans *= mpow(2, K);
  cout << ans << endl;
}