// Author: Rushin Shah
#include <bits/stdc++.h>
#define int long long
#define inf (LLONG_MAX / 5)
using namespace std;
// constexpr int MOD = 1e9 + 7;
const int MOD = 998244353;
int inv(int a, int b = MOD - 2);
struct Mint
{
int val;
Mint(int v) : val(v) {}
Mint() : val(0) {}
Mint operator+(const Mint &b) const
{
Mint n = val + b.val;
n.val %= MOD;
return n;
}
Mint operator-(const Mint &b) const
{
Mint n = val - b.val;
if (n.val < 0)
n += MOD;
return n;
}
Mint operator*(const Mint &b) const
{
Mint n = val * b.val;
n.val %= MOD;
return n;
}
Mint operator/(const Mint &b) const
{
Mint n = val * inv(b.val);
n.val %= MOD;
return n;
}
Mint &operator+=(const Mint &b)
{
this->val += b.val;
this->val %= MOD;
return *this;
}
Mint &operator-=(const Mint &b)
{
this->val -= b.val;
if (this->val < 0)
this->val += MOD;
return *this;
}
Mint &operator*=(const Mint &b)
{
this->val *= b.val;
this->val %= MOD;
return *this;
}
Mint operator/=(const Mint &b)
{
this->val *= inv(b.val);
this->val %= MOD;
return *this;
}
Mint operator++(int32_t)
{
Mint tmp = *this;
this->val += 1;
return tmp;
}
Mint &operator++()
{
this->val += 1;
return *this;
}
bool operator<(const Mint &b) const
{
return val < b.val;
}
bool operator<=(const Mint &b) const
{
return val <= b.val;
}
bool operator>(const Mint &b) const
{
return val > b.val;
}
bool operator>=(const Mint &b) const
{
return val >= b.val;
}
operator int() const
{
return val;
}
friend std::ostream &operator<<(std::ostream &os, const Mint &b)
{
return os << b.val;
}
friend std::istream &operator>>(std::istream &is, Mint &b)
{
is >> b.val;
return is;
}
};
Mint bin_pow(int a, int b)
{
if (!b)
return 1;
Mint g = bin_pow(a, (b >> 1));
g *= g;
if (b & 1)
g *= a;
return g;
}
int inv(int a, int b)
{
return bin_pow(a, b);
}
// -----------------------PRIME TIME--------------------------------------------
// constexpr int primeN = 1000000 + 5;
// bitset<primeN> is_prime;
// int low[primeN];
// vector<int> primes;
// void prime_it()
// {
// is_prime.set();
// for (int i = 2; i < primeN; i++)
// {
// if (!is_prime[i])
// continue;
// primes.push_back(i);
// low[i] = i;
// for (int j = i * i; j < primeN; j += i)
// {
// is_prime.reset(j);
// low[j] = i;
// }
// }
// }
// ---------------------------------DAILY USE--------------------------------------------------------------
constexpr int maxN = 2050;
int n, m, d;
int a[maxN][maxN];
Mint dp[maxN][maxN][2];
Mint pre_dp[maxN][maxN][2];
// REMEMBER TO - USE BS - Find an Invariant - DP[find subproblems]
// REMEBER TO - Focus on any imp constraints or find one
void solve()
{
cin >> n >> m >> d;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
char x;
cin >> x;
if (x == 'X')
a[i][j] = 1;
else
a[i][j] = 0;
}
}
for (int j = 1; j <= m; j++)
{
if (a[n][j])
{
dp[n][j][0] = 1;
}
}
for (int j = 1; j <= m; j++)
{
if (a[n][j])
{
int l = max(0ll, j - d - 1), r = max(n, j + d);
dp[n][j][1] += pre_dp[n][r][0] - pre_dp[n][l][0] - dp[n][j][0];
}
}
for (int j = 1; j <= m; j++)
{
pre_dp[n][j][0] += pre_dp[n][j - 1][0] + dp[n][j][0];
pre_dp[n][j][1] += pre_dp[n][j - 1][1] + dp[n][j][1];
}
for (int i = n - 1; i > 0; i--)
{
for (int j = 0; j <= m; j++)
{
for (int k = 0; k < 2; k++)
{
dp[i][j][k] = 0;
pre_dp[i][j][k] = 0;
}
}
for (int j = 1; j <= m; j++)
{
if (!a[i][j])
continue;
for (int k = 0; k < 2; k++)
{
if (k == 0)
{
int l = max(0ll, j - d - 1), r = max(n, j + d);
dp[i][j][k] += pre_dp[i + 1][r][0] - pre_dp[i + 1][l][0];
dp[i][j][k] += pre_dp[i + 1][r][1] - pre_dp[i + 1][l][1];
}
else
{
int l = max(0ll, j - d - 1), r = max(n, j + d);
dp[i][j][k] += pre_dp[i][r][0] - pre_dp[i][l][0] - dp[i][j][0];
}
}
}
for (int j = 1; j <= m; j++)
{
pre_dp[i][j][0] += pre_dp[i][j - 1][0] + dp[i][j][0];
pre_dp[i][j][1] += pre_dp[i][j - 1][1] + dp[i][j][1];
}
}
cout << pre_dp[1][m][0] + pre_dp[1][m][1] << "\n";
}
int32_t main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
// prime_it();
int t = 1;
cin >> t;
// cout << fixed << setprecision(7);
for (int i = 1; i <= t; i++)
{
solve();
}
return 0;
}