//第i个城市到第j个城市的概率ma[i][j]
//第i天的天气天气wet[i]
//第i个城市天气为j的概率wet_m[i][j]
//Hovey从0点開始,找出其概率最大的路线
//dp[i][j] 表示在第i天Hovey在第j个城市在全部路线的最大概率
//dp[i][j] = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]]
//可是因为精度问题,须要取对数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std ;
const int maxn = 1010 ;
const double inf = 1e50;
const double eps = 1e-14 ;
struct node
{
int pre ;
double p ;
}dp[maxn][maxn] ;
double ma[maxn][maxn] ;
double wet_m[maxn][maxn] ;
int wet[maxn] ;
int ans[maxn] ;
int main()
{
//freopen("in.txt" ,"r" ,stdin) ;
int T ;
scanf("%d" ,&T) ;
int n , m , w ;
while(T--)
{
scanf("%d%d%d", &n , &m , &w) ;
for(int i = 1;i <= n;i++)
scanf("%d" , &wet[i]) ;
for(int i = 0;i < m;i++)
for(int j = 0 ;j < m;j++)
{
scanf("%lf" , &ma[i][j]) ;
if(ma[i][j]<=0)ma[i][j] = -inf ;
else
ma[i][j] = log(ma[i][j]) ;
}
for(int i = 0;i < m;i++)
for(int j = 0;j < w;j++)
{
scanf("%lf" , &wet_m[i][j]) ;
if(wet_m[i][j] <= 0)wet_m[i][j] = -inf ;
else
wet_m[i][j] = log(wet_m[i][j]);
}
//memset(dp , 0 , sizeof(dp)) ;
for(int i = 0;i <= n;i++)
for(int j = 0;j <= m;j++)
dp[i][j].p = -inf ;
dp[0][0].p = 0 ;
for(int i = 1;i <= n;i++)
for(int j = 0 ;j < m;j++)
for(int k = 0;k < m ;k++)
{
double temp = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]] ;
if(temp > dp[i][j].p)
{
dp[i][j].p = temp;
dp[i][j].pre = k ;
}
}
double Max = -inf ;
int pos = 0;
for(int j = 0;j < m;j++)
if(dp[n][j].p > Max+eps)
{
pos = j ;
Max = dp[n][j].p ;
}
int pr = pos ;
for(int i = n ;i > 0 ;i--)
{
ans[i] = pr;
pr = dp[i][pr].pre ;
}
for(int i = 1;i <= n;i++)
printf("%d%c" , ans[i] , i == n ?' ':' ') ;
}
}
//第i天的天气天气wet[i]
//第i个城市天气为j的概率wet_m[i][j]
//Hovey从0点開始,找出其概率最大的路线
//dp[i][j] 表示在第i天Hovey在第j个城市在全部路线的最大概率
//dp[i][j] = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]]
//可是因为精度问题,须要取对数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std ;
const int maxn = 1010 ;
const double inf = 1e50;
const double eps = 1e-14 ;
struct node
{
int pre ;
double p ;
}dp[maxn][maxn] ;
double ma[maxn][maxn] ;
double wet_m[maxn][maxn] ;
int wet[maxn] ;
int ans[maxn] ;
int main()
{
//freopen("in.txt" ,"r" ,stdin) ;
int T ;
scanf("%d" ,&T) ;
int n , m , w ;
while(T--)
{
scanf("%d%d%d", &n , &m , &w) ;
for(int i = 1;i <= n;i++)
scanf("%d" , &wet[i]) ;
for(int i = 0;i < m;i++)
for(int j = 0 ;j < m;j++)
{
scanf("%lf" , &ma[i][j]) ;
if(ma[i][j]<=0)ma[i][j] = -inf ;
else
ma[i][j] = log(ma[i][j]) ;
}
for(int i = 0;i < m;i++)
for(int j = 0;j < w;j++)
{
scanf("%lf" , &wet_m[i][j]) ;
if(wet_m[i][j] <= 0)wet_m[i][j] = -inf ;
else
wet_m[i][j] = log(wet_m[i][j]);
}
//memset(dp , 0 , sizeof(dp)) ;
for(int i = 0;i <= n;i++)
for(int j = 0;j <= m;j++)
dp[i][j].p = -inf ;
dp[0][0].p = 0 ;
for(int i = 1;i <= n;i++)
for(int j = 0 ;j < m;j++)
for(int k = 0;k < m ;k++)
{
double temp = dp[i-1][k].p+ma[k][j]+wet_m[j][wet[i]] ;
if(temp > dp[i][j].p)
{
dp[i][j].p = temp;
dp[i][j].pre = k ;
}
}
double Max = -inf ;
int pos = 0;
for(int j = 0;j < m;j++)
if(dp[n][j].p > Max+eps)
{
pos = j ;
Max = dp[n][j].p ;
}
int pr = pos ;
for(int i = n ;i > 0 ;i--)
{
ans[i] = pr;
pr = dp[i][pr].pre ;
}
for(int i = 1;i <= n;i++)
printf("%d%c" , ans[i] , i == n ?' ':' ') ;
}
}