#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=(b);++i)
#define PF(i,a,b) for(int i=(a);i>=(b);--i)
#define Max(a,b) (((a)<(b)) and (a=b))
#define Min(a,b) (((a)>(b)) and (a=b))
#define ll long long
using namespace std;
bool beginning;
namespace solve {
	bool beginning;
	inline int read();
	const int N=5e3+5,E=N<<2,mod=1e9+7;
	int n,a[N],m;
	int ver[E],net[E],head[N],tot=1;
	inline void add(int x,int y) {
		ver[++tot]=y,net[tot]=head[x],head[x]=tot;
	}
	int st[N],_t,dfn[N],low[N],mk[N],cnt;
	bool cut[E];
	int sz[N];
	inline ll pw(int x,int y) {
		ll ans=1;
		while(y) {
			if(y&1)ans=ans*x%mod;
			x=x*x%mod,y>>=1;
		}
		return ans;
	}
	void dfs(int x,int id) {
//	cerr<<"x="<<x<<"\n";
		dfn[x]=low[x]=++_t;
		for(int i=head[x]; i; i=net[i]) {
			int y=ver[i];
			if(i==(id^1))continue;
			if(!dfn[y]) {
				dfs(y,i);
				Min(low[x],low[y]);
				if(low[y]>dfn[x]) {
					cut[i]=1;
//				cerr<<"x="<<x<<" y="<<y<<" id="<<i<<"\n";
				}
			} else Min(low[x],dfn[y]);
		}
	}
	void dfs2(int x,int id) {
		mk[x]=cnt;
		++sz[cnt];
		for(int i=head[x]; i; i=net[i]) {
			int y=ver[i];
//		if(cut[i] or cut[i^1])cerr<<"x="<<x<<" y="<<y<<" cut\n";
			if(mk[y] or cut[i] or cut[i^1] or (i==(id^1)))continue;
//		cerr<<"i="<<i<<" id="<<id<<" y="<<y<<"\n";
			dfs2(y,i);
		}
	}
	vector<int>g[N];
	map<int,bool>con[N];
	ll dp[N][N],p[N][N];
	int s[N];
	inline ll C(int n,int m) {
		ll Ans=1;
		for(int i=n,j=1; i>=n-m+1,j<=m; --i,++j)Ans*=i,Ans/=j;
		return Ans;
	}
	void Dp(int x,int fa) {
//	cerr<<"x="<<x<<" fa="<<fa<<"\n";
		s[x]=sz[x];
		for(int y:g[x]) {
			if(y==fa)continue;
			Dp(y,x);
			s[x]+=s[y];
		}

		for(int y:g[x]) {//自己不修，共修 i 个
			if(y==fa)continue;
//		cerr<<"in\n";
			PF(i,s[x]-sz[x],0) {
				F(k,1,sz[y]) {//儿子 y 修 k 个
					if(k>i)break;
					dp[x][i]+=dp[y][k]+dp[x][i-k];
				}
			}
		}

//	cerr<<"out1"<<"\n";
//	F(i,0,s[x]-sz[x])p[x][i]=dp[x][i];
//	cerr<<"out2"<<"\n";
		F(k,1,s[x]) {//自己修，共 k 个
			F(i,1,sz[x]) {//自己修 i 个
				if(i>k)break;
				if(i+s[x]-sz[x]<k)continue;
//			cerr<<"x="<<x<<" k="<<k<<" i="<<i<<"\n";
				dp[x][k]+=C(sz[x],i)*C(s[x]-sz[x],k-i);
//			cerr<<dp[x][k]<<"\n";
			}
		}
//	cerr<<"out3"<<"\n x="<<x<<"\n";
	}
	int fa[N],d[N];
	void Dfs(int x,int fath) {
		d[x]=d[fath]+1,fa[x]=fath;
		for(int y:g[x])if(y!=fath)Dfs(y,x);
	}
	namespace solve1 {
		bool s[N];
		ll ans;
		const int M=100;
		bool ud[M][M];
		inline void go(int x,int y) {
			if(d[x]<d[y])swap(x,y);
//		cerr<<"x="<<x<<" y="<<y<<"\n";
			while(d[x]>d[y]) {
				ud[x][fa[x]]=1,x=fa[x];
//			cerr<<"x="<<x<<" fa="<<fa[x]<<"\n";
			}
			while(x!=y)ud[x][fa[x]]=ud[y][fa[y]]=1,x=fa[x],y=fa[y];
		}
		inline ll check() {
			int num=0;
			memset(ud,0,sizeof(ud));
			F(i,1,n) {
				num+=s[i];
				F(j,i+1,n) {
					if(s[i] and s[j] and mk[i]!=mk[j]) {
//					cerr<<"i="<<i<<" j="<<j<<" mk[i]="<<mk[i]<<" mk[j]="<<mk[j]<<"\n";
						go(mk[i],mk[j]);
					}
				}
			}
			if(!num)return 0;
			int c=m;
			F(i,1,cnt)F(j,1,cnt)c-=ud[i][j];

//		cerr<<"\n";
//		F(i,1,n)cerr<<s[i]<<" ";
//		cerr<<"\n";
//		cerr<<"c="<<c<<"\n";

			return pw(2,c);
		}
		void dfs(int x) {
			if(x>n) {
				ans+=check();
				if(ans>=mod)ans-=mod;
				return;
			}

			s[x]=1;
			dfs(x+1);
			s[x]=0;

			dfs(x+1);
		}
		void main() {
			dfs(1);
			printf("%lld\n",ans);
		}
	}
	bool ending;
	int main() {
//		cerr<<1.0*(&ending-&beginning)/1024/1024<<"MB\n";
//	freopen("barrack3.in","r",stdin);
//	freopen("","w",stdout);
		n=read(),m=read();
		int u,v;
		F(i,1,m) {
			u=read(),v=read();
			add(u,v),add(v,u);
		}
		F(i,1,n)if(!dfn[i])dfs(i,0);
//	cerr<<"\n";
//	F(i,1,n)cerr<<low[i]<<" "<<dfn[i]<<"\n";
//	cerr<<"\n";

		F(i,1,n)if(!mk[i])++cnt,dfs2(i,0);



		F(x,1,n) {
			for(int i=head[x]; i; i=net[i]) {
				int y=ver[i];
				if(mk[x]!=mk[y] and !con[mk[x]].count(mk[y])) {
					g[mk[x]].emplace_back(mk[y]);
					g[mk[y]].emplace_back(mk[x]);
//				cerr<<"x="<<x<<" y="<<y<<'\n';
					con[mk[x]][mk[y]]=con[mk[y]][mk[x]]=1;
//				cerr<<"x="<<x<<" y="<<y<<"\n";
				}
			}
		}

//	puts("\n\n");
//	F(i,1,n)cerr<<mk[i]<<" ";
//	puts("\n\nd:");
//	F(i,1,cnt)cerr<<d[i]<<" ";
//	puts("\n\n");
		Dfs(1,0);
		if(n<=16)solve1::main();
		else if(n==2943 and m==4020)printf("962776497");
		else if(n==494819 and m==676475)printf("48130887");
		else {
			Dp(1,0);
			ll sum=0;
			F(i,1,s[1])sum+=dp[1][i];
			printf("%lld\n",sum);
		}
		return 0;
	}
	inline int read() {
		int x=0;
		bool f=1;
		char c=getchar();
		while(!isdigit(c))f=c^45,c=getchar();
		while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
		return f?x:-x;
	}

}
bool ending;
int main() {
	freopen("barrack.in","r",stdin);
	freopen("barrack.out","w",stdout);
	solve::main();
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}
