//POJ 2396 上下界可行流
//引用这位仁兄的解题报告:http://hi.baidu.com/zfy0701/blog/item/6449d82a64e15e3e5343c1ba.html
#include <iostream>
#include <algorithm>
using namespace std;
const int inf=1<<28;
int n,m,s,t,ds,dt;
const int VMAX = 300;
const int EMAX = 50000;
const int null = -1;
struct Edge
{
int adj,next,re; //指向的点,下一边的下标,逆边的下标
int r,f; //余留网边的容量和流量
int bot; //下界
}h[EMAX+10]; //用下标模拟指针构邻接表
int p[VMAX+10],c;
int gap[VMAX+10],pre[VMAX+10],dis[VMAX+10];
int bottom[VMAX+10][VMAX+10],top[VMAX+10][VMAX+10];
//插边,k,l为端点,cap为边容量
void insert(int k,int l,int bot,int top)
{
h[++c].adj=l;
h[c].r=top;
h[c].bot=bot;
h[c].next=p[k];
p[k]=c;
h[c].f=0;
h[c].re=c+1;
//逆边
h[++c].adj=k;
h[c].r=h[c].bot=h[c].f=0;
h[c].next=p[l];
p[l]=c;
h[c].re=c-1; //与上面对应
}
int sap(int s,int t,int N) //N为点数(包括源汇)
{
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
gap[0]=N;
int u=s,ca=inf,ans=0;
while (dis[s]<N)
{
while (1)
{
bool flag=false;
for (int j=p[u];j!=null;j=h[j].next)
{
int i=h[j].adj;
if (h[j].r && dis[u]==dis[i]+1)
{
ca=min(ca,h[j].r);
pre[i]=j;u=i; //注意邻接表版的pre表示的是边
if (i==t)
{
ans+=ca;
while (i!=s)
{
u=pre[i];
int re=h[u].re;
h[u].f+=ca;
h[re].f=-h[u].f;
h[u].r-=ca;
h[re].r+=ca;
i=h[re].adj;
}
u=s;ca=inf;
}
flag=true;
break;
}
}
if (!flag) break;
}
int Min=N;
for (int j=p[u];j!=null;j=h[j].next)
if (h[j].r && dis[h[j].adj]<Min)
Min=dis[h[j].adj];
if (--gap[dis[u]] == 0) break;
gap[dis[u]=Min+1]++;
if (u!=s) u=h[h[pre[u]].re].adj;
}
return ans;
}
void init()
{
c=-1;
memset(p,-1,sizeof(p));
}
int in[VMAX+10],out[VMAX+10];
int ind[VMAX+10][VMAX+10];
bool limit(int i,int j,char *op,int val)
{
if (strcmp(op,"=")==0)
{
if (val<bottom[i][j] || top[i][j]!=-1 && val>top[i][j]) return false;
bottom[i][j]=top[i][j]=val;
}
else if (strcmp(op,"<")==0)
{
--val;
if (val<bottom[i][j]) return false;
if (top[i][j]==-1 || top[i][j]>val) top[i][j]=val;
}
else
{
++val;
if (top[i][j]!=-1 && val>top[i][j]) return false;
if (val>bottom[i][j]) bottom[i][j]=val;
}
return true;
}
int main()
{
int tmm;
scanf("%d",&tmm);
bool first=true;
while (tmm--)
{
if (first) first=false;
else printf("/n");
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d%d",&n,&m);
s=0,t=n+m+1;
init();
int a,b,e,count;
char op[5];
for (int i=1;i<=n;i++)
{
scanf("%d",&a);
insert(s,i,a,a);
out[s]+=a;in[i]+=a;
}
for (int i=n+1;i<=n+m;i++)
{
scanf("%d",&a);
insert(i,t,a,a);
out[i]+=a;in[t]+=a;
}
memset(bottom,0,sizeof(bottom));
memset(top,-1,sizeof(top));
scanf("%d",&count);
bool flag=true;
while (count--)
{
scanf("%d%d%s%d",&a,&b,op,&e);
if (!flag) continue;
if (a==0)
{
for (a=1;a<=n;a++)
{
if (b==0)
{
for (b=1;b<=m;b++) if (!(limit(a,b,op,e))) flag=0;
}
else if ( !limit(a,b,op,e) ) flag=0;
}
}
else if (b==0)
{
for (b=1;b<=m;b++) if (!limit(a,b,op,e)) flag=0;
}
else if (!limit(a,b,op,e)) flag=0;
}
if (!flag)
{
printf("IMPOSSIBLE/n");
continue;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
ind[i][j]=c+1;
insert(i,n+j,bottom[i][j],top[i][j]==-1?inf:top[i][j]);
in[n+j]+=bottom[i][j];out[i]+=bottom[i][j];
}
ds=n+m+2,dt=n+m+3;
//拆边,附加源汇
for (int i=0;i<=n+m+1;i++)
for (int j=p[i];j!=null;j=h[j].next)
{
h[j].r-=h[j].bot;
}
for (int i=0;i<=n+m+1;i++)
{
insert(ds,i,0,in[i]);
insert(i,dt,0,out[i]);
}
insert(t,s,0,inf); //插入边(t,s,0,inf)
sap(ds,dt,n+m+4); //求一次最大流
flag=true;
for (int i=p[ds];i!=null;i=h[i].next)
{
if (h[i].r) { flag= false; break;}
}
if (!flag)
{
printf("IMPOSSIBLE/n");
continue;
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
if (j!=1) printf(" ");
printf("%d",h[ind[i][j]].f+h[ind[i][j]].bot);
}
printf("/n");
}
}
system("pause");
return 0;
}