// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <queue>

#include <map>

#include <set>

#include <vector>

#include <string>

#include <stack>

#include <bitset>

#define maxn 100009

using namespace std;

const int MOD=1e9+7;

int p[maxn];

long long bin[maxn];

int findset(int x)

{

	return x==p[x]?x:p[x]=findset(p[x]);

}

void unionset(int x,int y)

{

	 p[findset(x)]=findset(y);

}

int main()

{

	int n,m,x,y;

	bin[0]=1;

	for(int i=1;i<maxn;i++)

		bin[i]=2*bin[i-1]%MOD;

	while(scanf("%d%d",&n,&m)!=EOF&&n+m)

	{

		for(int i=0;i<=n;i++)

			p[i]=i;

		for(int i=0;i<m;i++)

		{

			scanf("%d%d",&x,&y);

			unionset(x,y);

		}

		int cnt=0;

		for(int i=1;i<=n;i++)

		{

			if(p[i]==i)

			{

				cnt++;

			}

		}

		int ans=bin[cnt];

		if(cnt!=n)

			ans=(ans+1)%MOD;

		printf("%d\n",ans);

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

using namespace std;

using LL = long long; using ll = LL;

using PLL = pair<LL, LL>; using pll = PLL;

using PII = pair<int, int>; using pii = PII;

const int INF = 1e9; const LL LINF = 1e18;

#define SZ(a) (int)a.size()

#define FOR(i,s,t) for(int i= s; i<t;i++)

#define ALL(a) a.begin(),a.end()

using VL = vector<LL>; using VLL = vector<VL>;



struct UnionFind {

	vector<int> data;

	UnionFind(int size) { init(size); }

	void init(int size) { data.clear(); data.resize(size, -1); }

	bool unite(int x, int y) {

		x = root(x); y = root(y);

		if (x != y) {

			if (data[y] < data[x]) swap(x, y);

			data[x] += data[y]; data[y] = x;

		}

		return x != y;

	}

	bool same(int x, int y) {

		return root(x) == root(y);

	}

	int root(int x) {

		return data[x] < 0 ? x : data[x] = root(data[x]);

	}

	int size(int x) {

		return -data[root(x)];

	}

};



void solve() {

	int N, M;

	while (cin >> N >> M, N) {

		UnionFind uf(N);

		FOR(i, 0, M) {

			int a, b;

			cin >> a >> b;

			a--, b--;

			uf.unite(a, b);

		}

		VL used(N, 0);

		int isgroup = 0;

		int cnt = 0;

		FOR(i, 0, N) {

			int root = uf.root(i);

			if (used[root])continue;

			cnt++;

			if (uf.size(root) != 1)isgroup=1;

			used[root] = 1;

		}

		LL nene = 1;

		const LL mod = 1e9 + 7;



		FOR(i, 0, cnt) {

			nene *= 2;

			nene %= mod;

		}

		nene += isgroup;

		nene %= mod;

		cout << nene << endl;

	}



}



int main() {

	cin.tie(0);

	ios_base::sync_with_stdio(false);

	solve();

	return 0;

}


// Fastest known solution for this problem:
#include<iostream>

#include<map>

#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;

typedef long long ll;

const ll mod = 1000000007;

 

int uf[100100], r[100100];

 

void init(int n){

  rep(i,n)uf[i] = i, r[i] = 0;

}

 

int find(int a){

  if(uf[a] == a)return a;

  return uf[a] = find(uf[a]);

}

 

void unite(int a,int b){

  a = find(a); b = find(b);

  if(a==b)return;

  if(r[a] < r[b])uf[a] = b;

  else{

    uf[b] = a;

    if(r[a] == r[b])r[b]++;

  }

}

 

ll pow(ll a, ll n){

  ll res = 1;

  while(n){

    if(n&1)(res *= a) %= mod;

    (a *= a) %= mod; n>>=1;

  }

  return res;

}

 

int n,m,a,b;

 

int main(){

  cin.tie(0);

  std::ios::sync_with_stdio(false);

 

  while(cin >> n >> m, n){

    init(n);

 

    rep(i,m){

      cin >> a >> b; a--; b--;

      unite(a,b);

    }

 

    map<int,int> g;

    rep(i,n)g[find(i)]++;

     

    ll ans = pow(2,g.size());

    if(m>0)ans++;

    cout << ans%mod << endl;

  }

}