把一组
x,y
x
,
y
看做一条边
因为是在一排,所以出现环就无解;又因为左右一共两个位置,所以一个点度数大于2也无解
然后就是一堆链的问题,对于长度为1的链,链内排列只有一种;对于其他的链,有正反两种
然后记得再算上这些链的全排列
代码如下:
#include<ctype.h>
#include<cstdio>
#define N 500050
#define MOD 989381
using namespace std;
inline int read(){
int x=0,f=1;char c;
do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));
do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));
return x*f;
}
typedef long long LL;
LL ans=1;
bool flag;
int n,m,x,y,tot;
int f[N],degree[N],num[N],a[N];
int Find(int x){
return f[x]==x?f[x]:f[x]=Find(f[x]);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
x=read();y=read();
a[y]=x;
if(a[a[y]]==y) continue;
degree[x]++;degree[y]++;
int fx=Find(x),fy=Find(y);
f[fx]=fy;
if(degree[x]>2 || degree[y]>2 || fx==fy) flag=true;
}
if(flag) return printf("0"),0;
for(int i=1;i<=n;i++)
num[Find(i)]++;
for(int i=1;i<=n;i++){
if(num[i]>1) ans<<=1,ans%=MOD;
if(num[i]) tot++;
}
while(tot) ans=ans*(tot--)%MOD;
printf("%lld",ans);
return 0;
}