/*
本题要判断图中两两可达, 在用强联通缩点后, 二次构图,进行拓扑排序, 在排序过程中若出现一个以上入度为零的点, 这次图不能满足
图中点两两可达,
*/
本题要判断图中两两可达, 在用强联通缩点后, 二次构图,进行拓扑排序, 在排序过程中若出现一个以上入度为零的点, 这次图不能满足
图中点两两可达,
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
const int M = 2005;
const int N = 6005;
struct node {
int to;
int next;
}num[N*2], num1[N];
int ins[M];
int dfn[M];
int low[M];
int rdu[M];
int cdu[M];
int sccf[M];
int vist[M];
int head1[M];
int head[M];
stack<int>s;
int index, cont;
int ans, flag;
int T, n, m, e, e1;
void init() {
e = 0;
e1 = 0;
index = 1;
cont = 0;
flag = true;
memset(num, 0, sizeof(num));
memset(head, -1, sizeof(head));
memset(head1, -1, sizeof(head1)); //开始忘记head1初始化,wa了很多次, 血的教训啊!
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(sccf, 0, sizeof(sccf));
memset(rdu, 0, sizeof(rdu));
memset(cdu,0, sizeof(cdu));
}
void add(int a, int b) {
num[e].to = b;
num[e].next = head[a];
head[a] = e++;
}
void add1(int a, int b) {
num1[e1].to = b;
num1[e1].next = head1[a];
head1[a] = e1++;
}
void Tanjian(int u) { //缩点,
int v;
dfn[u] = low[u] = index++;
ins[u] = 1;
s.push(u);
for(int k = head[u]; k != -1; k = num[k].next) {
v = num[k].to;
if(!dfn[v]) {
Tanjian(v);
low[u] = min(low[u], low[v]);
}
else if(ins[v]) {
low[u] = min(low[u], low[v]);
}
}
if(low[u] == dfn[u]) {
cont++;
do {
v = s.top();
s.pop();
sccf[v] = cont;
ins[v] = 0;
}while(u != v);
}
}
void conggougraph() {
int v;
for(int i = 1; i <= n; i++) {
for(int k = head[i]; k != -1; k = num[k].next) {
v = num[k].to;
if(sccf[i] != sccf[v]) { //使用缩点后编号构图,
add1(sccf[i], sccf[v]);
rdu[sccf[v]]++;
}
}
}
// printf("here\n");
memset(vist, 0, sizeof(vist));
for(int k = 1; k < cont; k++) {
int coum = 0;
int sign = 0;
for(int i = 1; i <= cont; i++) {
if(rdu[i] == 0 && !vist[i]) { //计算入度为零个数,
sign = i;
vist[i] = 1; //标记此点已被删除,
coum++;
}
}
if(coum > 1) { //判断入度为零个数,大于1 标记不满足,
flag = false;
}
else if(flag) {
// printf("ssss%d\n", sign);
for(int j = head1[sign]; j != -1; j = num1[j].next) { //把要删除点到达的点的入度减一;
int v = num1[j].to;
rdu[v]--;
}
}
}
}
int main()
{
int a, b;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
init();
for(int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
add(a, b);
}
for(int i = 1; i <= n; i++) { //Tanjian() 缩点模板;
if(!dfn[i]) {
Tanjian(i);
}
}
// printf("%d\n", cont);
conggougraph(); //二次构图;
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}