杜老师说的哦
据说有人n*3^n卡过去 ? UOJ上需要卡常哦
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int M=1505;
const int N=25;
struct edge{
int u,v,w;
int next;
}G[M];
int head[N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int n,m;
ll f[N][N],Ans;
#define V G[p].v
int Map[N][N];
int lst[N][N];
int c,a[N];
inline void dfs(int u,int fa){
for (int p=head[u];p;p=G[p].next)
if (V!=fa)
dfs(V,u);
for (int i=1;i<=c;i++){
f[u][i]=1;
for (int p=head[u];p && f[u][i];p=G[p].next)
if (V!=fa){
ll tem=0;
for (int j=1;j<=*lst[i];j++)
tem+=f[V][lst[i][j]];
f[u][i]*=tem;
}
}
}
int main(){
int iu,iv;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m);
for (int i=1;i<=m;i++)
read(iu),read(iv),Map[iu][iv]=Map[iv][iu]=1;
for (int i=1;i<n;i++)
read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum);
for (int t=0;t<(1<<n);t++){
c=0;
for (int i=1;i<=n;i++) if (t>>(i-1)&1) a[++c]=i;
for (int i=1;i<=c;i++){
*lst[i]=0;
for (int j=1;j<=c;j++) if (Map[a[i]][a[j]]) lst[i][++*lst[i]]=j;
}
dfs(1,0);
ll tem=0;
for (int i=1;i<=c;i++) tem+=f[1][i];
if (~(n-c)&1) Ans+=tem; else Ans-=tem;
}
printf("%lld\n",Ans);
return 0;
}