/*
在2-sat中,i和j冲突,连两条有向边i-->j',j-->i'。
那么当i和j要求不同时,如果i和j相同,就表示i和j冲突,连两条有向边i-->j',j-->i'。
那么当i和j要求相同时,如果i和j不同,就表示i和j冲突,连两条有向边i-->j',j-->i'。
求强连通分量,如果i和i'在同一SCC中,则无解,输出no,否则输出yes。
*/
#include<cstdio>
#include<cstring>
#include<vector>
#define N 20005
using namespace std;
int n,m,t,tt,num,adj[N];
int a[2][N],scc[N],stk[N],stk2[N],dfn[N];
struct edge
{
int v,pre;
} e[N];
void insert(int u,int v)
{
e[num].v=v;
e[num].pre=adj[u];
adj[u]=num++;
}
void tarjan(int cur,int& sig,int& num)
{
int i,v;
dfn[cur]=++sig;
stk[++stk[0]]=stk2[++stk2[0]]=cur;
for(i=adj[cur]; ~i; i=e[i].pre)
if(0==dfn[v=e[i].v])
tarjan(v,sig,num);
else if(0==scc[v])
while(dfn[stk2[stk2[0]]]>dfn[v])
stk2[0]--;
if(stk2[stk2[0]]==cur)
{
stk2[0]--;
num++;
do
{
scc[stk[stk[0]]]=num;
}
while(stk[stk[0]--]!=cur);
}
}
int Gabow()
{
int i,sig,num;
sig=num=stk[0]=stk2[0]=0;
memset(scc,0,sizeof(scc));
memset(dfn,0,sizeof(dfn));
for(i=0; i<n*2; i++)
if(0==dfn[i])
tarjan(i,sig,num);
return num;
}
bool check()
{
for(int i=0; i<n*2; i+=2)
if(scc[i]==scc[i+1])
return 0;
return 1;
}
int main()
{
int i,j,u,v,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
scanf("%d",&a[0][i]);
a[0][i]--;
a[1][i]=(a[0][i]+2)%3;
}
num=0;
memset(adj,-1,sizeof(adj));
while(m--)
{
scanf("%d%d%d",&u,&v,&k);
u--;
v--;
for(i=0; i<2; i++)
for(j=0; j<2; j++)
if(k&&a[i][u]==a[j][v]||!k&&a[i][u]!=a[j][v])
{
insert(2*u+i,2*v+j^1);
insert(2*v+j,2*u+i^1);
}
}
Gabow();
printf("Case #%d: ",++tt);
if(check())
puts("yes");
else
puts("no");
}
}