Since all participants see themselves as the first, their relative order in the chat cannot be determined based on their provided sequence. However, the relative orders of all other participants can be determined.
For each participants, the sequence a 1 … n a_{1\dots n} a1…n that they provided can be reduced to n − 2 n-2 n−2 constraints of relative order (i.e. for i ∈ ( 1 , n ) i\in (1,n) i∈(1,n), a i a_i ai must be in front of a i + 1 a_{i+1} ai+1 in the ultimate sequence). Then, we can further reduce this k k k sequences into a directed graph, with the n n n users as nodes and the k ⋅ ( n − 2 ) k\cdot (n-2) k⋅(n−2) constraints as edges.
If the resulting graph is a Directed Acyclic Graph, we can numder (sort) the nodes in a manner that satisfies all k ⋅ ( n − 2 ) k\cdot (n-2) k⋅(n−2) constraints through topological sort. However, it is impossible to construct the final order when loops exist for the following reason.
If there exists a directed path from node i i i to j j j, element i i i must be ranked in front of element j j j in the final order. Therefore, when there is also a directed path from j j j to i i i, a contradiction emerges.
Therefore, we can simply check if the above constructed graph is a DAG, and output accordingly.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int Maxn=2e5+10;
int dfn[Maxn],low[Maxn];
int s[Maxn],f[Maxn],a[Maxn];
bool vis[Maxn];
vector <int> e[Maxn];
int n,m,cnt,timecnt;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
void tarjan(int x)
{
dfn[x]=low[x]=++timecnt;
vis[x]=1,s[++cnt]=x;
for(int i=0;i<e[x].size();++i)
{
int y=e[x][i];
if(!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(vis[y])low[x]=min(low[x],low[y]);
}
if(dfn[x]==low[x])
{
while(cnt)
{
int y=s[cnt--];
vis[y]=0,f[y]=x;
if(x==y)break;
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
int T=read();
while(T--)
{
n=read(),m=read();
for(int j=1;j<=m;++j)
{
for(int i=1;i<=n;++i)
a[i]=read();
for(int i=2;i<n;++i)
e[a[i]].push_back(a[i+1]);
}
if(m==1){puts("YES");goto GG;}
for(int i=1;i<=n;++i)
if(!dfn[i])tarjan(i);
for(int i=1;i<=n;++i)
if(f[i]!=i){puts("NO");goto GG;}
puts("YES");
GG:timecnt=0;
fill(dfn,dfn+1+n,0);
fill(low,low+1+n,0);
fill(f,f+1+n,0);
for(int i=1;i<=n;++i)
e[i].clear();
}
return 0;
}