// Author: Mubasshir Chowdhury
#include "bits/stdc++.h"
// #include "bits/extc++.h"
// using namespace __gnu_pbds;
#ifndef debug
#define debug(...)
#endif
using namespace std;
#define int long long
#define ll long long
#define pii pair<int, int>
#define vi vector<int>
#define vp vector<pii>
#define vvi vector<vi>
#define a3 array<int, 3>
#define a4 array<int, 4>
#define sz(v) (int)(v).size()
#define all(v) begin(v), end(v)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define uid(l, r) uniform_int_distribution<ll>(l, r)(rng)
template <class T> using V = vector<T>;
template <typename T> bool chmin(T& a, T b) {
return b < a ? a = b, true : false;
}
template <typename T> bool chmax(T& a, T b) {
return b > a ? a = b, true : false;
}
// template <typename T>
// using ordered_set =
// tree<T, null_type, less<T>, rb_tree_tag,
// tree_order_statistics_node_update>;
map<a3, bool> dp;
bool calc(int h, int w, int k) {
if (k < max(h, w) / 2 || k * 4 > h * w)
return false;
if (k == max(h, w) / 2)
return true;
if (k == h * w / 4)
return true;
a3 state = a3({h, w, k});
if (dp.contains(state))
return dp[state];
if (h >= 4 && w >= 4 && calc(h - 2, w - 2, k - 1)) {
return dp[state] = true;
}
for (int h2 = 2; h2 <= h - 2; h2 += 2) {
for (int k1 = max(h2, w) / 2; k1 * 4 <= h2 * w; k1++) {
if (calc(h2, w, k1) && calc(h - h2, w, k - k1)) {
return dp[state] = true;
}
}
}
for (int w2 = 2; w2 <= w - 2; w2 += 2) {
for (int k1 = max(h, w2) / 2; k1 * 4 <= h * w2; k1++) {
if (calc(h, w2, k1) && calc(h, w - w2, k - k1)) {
return dp[state] = true;
}
}
}
return dp[state] = false;
}
int col;
vvi grid;
void charpash(int x, int y, int h, int w) {
for (int i = x; i < x + h; i++) {
grid[i][y] = col;
grid[i][y + w - 1] = col;
}
for (int j = y; j < y + w; j++) {
grid[x][j] = col;
grid[x + h - 1][j] = col;
}
col++;
}
void tt(int x, int y, int h, int w) {
for (int i = x; i < x + h; i += 2) {
for (int j = y; j < y + w; j += 2) {
grid[i][j] = grid[i + 1][j] = grid[i][j + 1] = grid[i + 1][j + 1] =
col++;
}
}
}
bool build(int x, int y, int h, int w, int k) {
if (!calc(h, w, k))
return false;
if (k == max(h, w) / 2) {
int hh = h, ww = w;
int xx = x, yy = y;
while (min(hh, ww) > 2) {
charpash(xx, yy, hh, ww);
xx++;
yy++;
hh -= 2;
ww -= 2;
}
tt(xx, yy, hh, ww);
return true;
}
if (k == h * w / 4) {
tt(x, y, h, w);
return true;
}
if (h >= 4 && w >= 4 && calc(h - 2, w - 2, k - 1)) {
charpash(x, y, h, w);
build(x + 1, y + 1, h - 2, w - 2, k - 1);
return true;
}
for (int h2 = 2; h2 <= h - 2; h2 += 2) {
for (int k1 = max(h2, w) / 2; k1 * 4 <= h2 * w; k1++) {
if (calc(h2, w, k1) && calc(h - h2, w, k - k1)) {
build(x, y, h2, w, k1);
build(x + h2, y, h - h2, w, k - k1);
return true;
}
}
}
for (int w2 = 2; w2 <= w - 2; w2 += 2) {
for (int k1 = max(h, w2) / 2; k1 * 4 <= h * w2; k1++) {
if (calc(h, w2, k1) && calc(h, w - w2, k - k1)) {
build(x, y, h, w2, k1);
build(x, y + w2, h, w - w2, k - k1);
return true;
}
}
}
assert(false);
return false;
}
void solve() {
int n, m, k;
cin >> n >> m >> k;
if (n % 2 || m % 2 || !calc(n, m, k)) {
cout << "NO\n";
} else {
cout << "YES\n";
col = 1;
grid.assign(n + 1, vi(m + 1, 0));
build(1, 1, n, m, k);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cout << grid[i][j] << " ";
}
cout << "\n";
}
}
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
cout.tie(0);
// cout << fixed << setprecision(15);
int T = 1;
cin >> T;
for (int ti = 1; ti <= T; ++ti) {
solve();
}
}