#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
int main()
{
ios_base::sync_with_stdio(false);
int n,m;
cin>>n>>m;
vector<vector<int>> G(n+5);
vector<int> deg(n+5);
vector<pair<int,int>> edges;
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
deg[u]++;deg[v]++;
G[u].push_back(v);G[v].push_back(u);
edges.emplace_back(u,v);
}
vector<int> ord(n+5);
iota(ord.begin(),ord.end(),0);
sort(ord.begin()+1,ord.begin()+n+1,[&](int x,int y){return deg[x]==deg[y]?x<y:deg[x]<deg[y];});
vector<int> pos(n+5);
for(int i=1;i<=n;i++)pos[ord[i]]=i;
long long ans=0;
auto solve=[&](auto &a,auto t)
{
/*
cerr<<"solve"<<endl;
for(int i=1;i<=t;i++)
{
for(int j=1;j<=t;j++)
cerr<<((a[i]>>j)&1);
cerr<<endl;
}
*/
int hf=(t+1)/2,rem=t-hf;
vector<long long> L(1<<hf),Ls(1<<hf),R(1<<rem),Rs(1<<rem);
R[0]=1;
Rs[0]=((1<<rem)-1);
for(int i=0;i<(1<<rem);i++)
{
if(not R[i])continue;
int tmp=Rs[i];
for(int j;tmp;tmp&=~(1<<j))
{
j=31-__builtin_clz(tmp);
R[i|(1<<j)]=1;
Rs[i|(1<<j)]=Rs[i]&(a[j+hf+1]>>(hf+1))&~(1<<j);
}
}
for(int j=0;j<rem;j++)
for(int i=0;i<(1<<rem);i++)
if(not ((i>>j)&1))
R[i|(1<<j)]+=R[i];
L[0]=1;
Ls[0]=((1ll<<t)-1);
for(int i=0;i<(1<<hf);i++)
{
if(not L[i])continue;
int tmp=Ls[i]&((1<<hf)-1);
for(int j;tmp;tmp&=~(1<<j))
{
j=31-__builtin_clz(tmp);
L[i|(1<<j)]=1;
Ls[i|(1<<j)]=Ls[i]&(a[j+1]>>1)&~(1<<j);
}
if(i&1)
{
// cerr<<"subset "<<i<<" add "<<R[Ls[i]>>hf]<<endl;
ans+=R[Ls[i]>>hf];
}
}
};
for(int i=1;i<=n;i++)
{
vector<int> idx(n+5);
int x=ord[i];
// cerr<<"order "<<i<<' '<<x<<endl;
int t=1;
idx[x]=t;
for(auto v:G[x])
{
if(pos[v]>pos[x])
{
++t;
idx[v]=t;
}
}
vector<long long> a(t+5);
for(auto [u,v]:edges)
{
if(idx[u] and idx[v])
{
// cerr<<"addedge "<<idx[u]<<' '<<idx[v]<<endl;
a[idx[u]]|=(1ll<<idx[v]);
a[idx[v]]|=(1ll<<idx[u]);
}
}
solve(a,t);
}
cout<<ans%MOD<<endl;
return 0;
}