Rt。
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int u,v,t,n,m,a[N];
struct node{
int from,to,nextt;
}mp[N];
int h[N],cnt;
void add(int x,int y){
mp[++cnt].to=y;
mp[cnt].from=x;
mp[cnt].nextt=h[x];
h[x]=cnt;
}
vector<int>edge[N];
int vis[N],low[N],num[N],dfn;
int scc[N],tot,stac[N],top,flag[N];
int in[N];
int black_in, black_all;
void init(){
memset(mp,0,sizeof(mp));
memset(h,0,sizeof(h));
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(num,0,sizeof(num));
memset(scc,0,sizeof(scc));
memset(stac,0,sizeof(stac));
memset(flag,0,sizeof(flag));
memset(in,0,sizeof(in));
memset(a,0,sizeof(a));
for(int i=0;i<N;i++)edge[i].clear();
dfn=tot=top=cnt=0;
black_in=black_all=0;
}
void tarjan(int u){
low[u]=num[u]=++dfn;
stac[++top]=u;
vis[u]=1;
for(int i=h[u];i;i=mp[i].nextt){
int v=mp[i].to;
if(!num[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]){
low[u]=min(low[u],num[v]);
}
}
if(low[u]==num[u]){
scc[u]=++tot;
vis[u]=0;
flag[tot]=a[u];
while(stac[top]!=u){
int x=stac[top];
scc[x]=tot;
vis[x]=0;
if(flag[tot]!=a[x]) flag[tot]= -1;
top--;
}
top--;
}
}
int topu(){ //!返回按照拓扑排序找到的第一个黑色点
queue<int>q;
while(!q.empty())q.pop();
for(int i=1;i<=tot;i++){
if(!in[i]){
if(flag[i]==1) return i;
q.push(i);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(flag[v]==1){
return v;
}
in[v]--;
if(!in[v])q.push(v);
}
}
}
void dfs(int u){
//! 沿着这条链走的必须全部为1;
if(flag[u]==1)black_in++;
else {
black_in=-1;return; // 经过了0就把着个设为-1,一定是不合法的
}
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
dfs(v);
}
return ;
}
void read(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
cin>>u>>v;
add(u,v);
}
}
void work(){
for(int i=1;i<=n;i++){ //先缩点
if(!num[i]){
tarjan(i);
}
}
for(int i=1;i<=tot;i++){ //? 判断有没有奇形怪状的节点
if(flag[i]==-1){
cout<<"N";
return;
}
if(flag[i]==1) black_all++;
}
if(black_all==0){ //! 如果全是白色点的话,后手必胜
cout<<"B";
return ;
}
for(int i=1;i<=cnt;i++){ // 建立新图
int x=scc[mp[i].from],y=scc[mp[i].to];
if(x!=y){
edge[x].push_back(y);
in[y]++;
}
}
//! 两个独立的黑色节点, 后手必胜
if(tot==2&&flag[1]==1&&flag[2]==1&&!edge[1].size()&&!edge[2].size()){
cout<<"B";
return ;
}
//! 只有两个节点,黑色 的点指向 白色 的点
if(tot==2){
if(edge[1].size()==1 &&flag[1]==1&&flag[2]==0){
cout<<"B";
return ;
}
if(edge[2].size()==1 &&flag[1]==0&&flag[2]==1){
cout<<"B";
return;
}
}
dfs(topu());
//! 输出A的条件
//! 在拓扑排序找到第一个黑色点的时候,记录下来
//! 然后从该点开始往后走,
//! 必须满足 所经过的点都是1 ,且经过了所有的 1
if(black_in==black_all){
cout<<"A";
} // 拓扑搜一遍
else {
cout<<"N";
}
return ;
}
signed main(){
cin>>t;
while(t--){
init();
read();
work();
}
return 0;
}