It's our faculty's 34th anniversary! To celebrate this great event, the Faculty of Computer Science, University of Indonesia (Fasilkom), held CPC - Coloring Pavements Competition. The gist of CPC is two players color the predetermined routes of Fasilkom in Blue and Red. There are N Checkpoints and M undirected predetermined routes. Routes i connects checkpoint U_i and V_i, for (1 ≤ i ≤ M). It is guaranteed that any pair of checkpoints are connected by using one or more routes.

The rules of CPC is as follows: 

  * Two players play in each round. One player plays as blue, the other plays as red. For simplicity, let's call these players Blue and Red. 
  * Blue will color every route in he walks on blue, Red will color the route he walks on red. Both players start at checkpoint number 1. Initially, all routes are gray. 
  * Each phase, from their current checkpoint, Blue and Red select a different gray route and moves to the checkpoint on the other end of the route simultaneously. 
  * The game ends when Blue or Red can no longer move. That is, there is no two distinct gray routes they can choose to continue moving. 



Chaneka is interested in participating. However, she does not want to waste much energy. So, She is only interested in the number of final configurations of the routes after each round. Turns out, counting this is also exhausting, so Chaneka asks you to figure this out!

Two final configurations are considered different if there is a route U in a different color in the two configurations.

Input

The first line contains two integers N and M. N (2 ≤ N ≤ 2 ⋅ 10^3) denotes the number of checkpoints, M (1 ≤ M ≤ 2 ⋅ N) denotes the number of routes. It is guaranteed that every checkpoint except checkpoint 1 has exactly two routes connecting it.

The next M lines each contains two integers U_i and V_i (1 ≤ U_i, V_i ≤ N, U_i ≠ V_i), which denotes the checkpoint that route i connects.

It is guaranteed that for every pair of checkpoints, there exists a path connecting them directly or indirectly using the routes. 

Output

Output a single integer which denotes the number of final configurations after each round of CPC modulo 10^9 + 7

Example

Input


5 6
1 2
2 3
3 4
4 1
1 5
5 1


Output


8

Note

Every possible final configuration for the example is listed below:

<image>

The blue-colored numbers give the series of moves Blue took, and the red-colored numbers give the series of moves Red took.
#include <bits/stdc++.h>
using namespace std;
long long n, m, c;
vector<long long> G[2005];
long long dp[2005][4005];
int ldp[2005][8005], rdp[2005][8005];
long long zero = 4002;
bool used[2005];
long long dfs(int v) {
  used[v] = true;
  for (long long(i) = (0); (i) <= ((int)G[v].size() - 1); (i)++) {
    if (used[G[v][i]]) continue;
    return dfs(G[v][i]) + 1;
  }
  return 1;
}
int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  long long u, v;
  for (long long(i) = (1); (i) <= (m); (i)++) {
    cin >> u >> v;
    G[u].push_back(v);
    G[v].push_back(u);
  }
  vector<long long> vec;
  used[1] = true;
  for (long long(i) = (0); (i) <= ((int)G[1].size() - 1); (i)++) {
    long long v = G[1][i];
    if (used[v]) continue;
    vec.push_back(dfs(v) + 1);
  }
  c = vec.size();
  dp[0][0] = 1;
  for (long long(i) = (0); (i) <= (c - 1); (i)++) {
    for (long long(j) = (0); (j) <= (m); (j)++) {
      (dp[i + 1][j] += dp[i][j]) %= 1000000007;
      if (j + vec[i] <= m) (dp[i + 1][j + vec[i]] += dp[i][j]) %= 1000000007;
    }
  }
  ldp[0][zero] = 1;
  for (long long(i) = (0); (i) <= (c - 1); (i)++) {
    for (long long(j) = (-m); (j) <= (m); (j)++) {
      (ldp[i + 1][zero + j] += ldp[i][zero + j]) %= 1000000007;
      if (j + vec[i] <= m)
        (ldp[i + 1][zero + j + vec[i]] += ldp[i][zero + j]) %= 1000000007;
      if (j - vec[i] >= -m)
        (ldp[i + 1][zero + j - vec[i]] += ldp[i][zero + j]) %= 1000000007;
    }
  }
  rdp[c + 1][zero] = 1;
  for (int i = c + 1; i >= 2; i--) {
    for (long long(j) = (-m); (j) <= (m); (j)++) {
      (rdp[i - 1][zero + j] += rdp[i][zero + j]) %= 1000000007;
      if (j + vec[i - 2] <= m)
        (rdp[i - 1][zero + j + vec[i - 2]] += rdp[i][zero + j]) %= 1000000007;
      if (j - vec[i - 2] >= -m)
        (rdp[i - 1][zero + j - vec[i - 2]] += rdp[i][zero + j]) %= 1000000007;
    }
  }
  long long ans = 0;
  if (m % 2 == 0) ans += dp[c][m / 2];
  for (long long(i) = (1); (i) <= (c); (i)++) {
    for (int j = vec[i - 1] - 2; j >= -vec[i - 1] + 2; j--) {
      for (long long(k) = (-m); (k) <= (m); (k)++) {
        if (k + j < -m || k + j > m) continue;
        ans += (long long)ldp[i - 1][zero + k] *
               (long long)rdp[i + 1][zero + k + j] % 1000000007 * 2 %
               1000000007;
        ans %= 1000000007;
      }
    }
  }
  if (m % 2) {
    for (long long(i) = (0); (i) <= (c + 1); (i)++) {
      for (long long(j) = (-m); (j) <= (m); (j)++) {
        ldp[i][zero + j] = rdp[i][zero + j] = 0;
      }
    }
    ldp[0][zero] = 1;
    for (long long(i) = (0); (i) <= (c - 1); (i)++) {
      for (long long(j) = (-m); (j) <= (m); (j)++) {
        if (j + vec[i] <= m)
          (ldp[i + 1][zero + j + vec[i]] += ldp[i][zero + j]) %= 1000000007;
        if (j - vec[i] >= -m)
          (ldp[i + 1][zero + j - vec[i]] += ldp[i][zero + j]) %= 1000000007;
      }
    }
    rdp[c + 1][zero] = 1;
    for (int i = c + 1; i >= 2; i--) {
      for (long long(j) = (-m); (j) <= (m); (j)++) {
        if (j + vec[i - 2] <= m)
          (rdp[i - 1][zero + j + vec[i - 2]] += rdp[i][zero + j]) %= 1000000007;
        if (j - vec[i - 2] >= -m)
          (rdp[i - 1][zero + j - vec[i - 2]] += rdp[i][zero + j]) %= 1000000007;
      }
    }
    for (long long(i) = (1); (i) <= (c); (i)++) {
      long long j = vec[i - 1] - 1;
      for (long long(k) = (-m); (k) <= (m); (k)++) {
        if (k + j < -m || k + j > m) continue;
        ans += (long long)ldp[i - 1][zero + k] *
               (long long)rdp[i + 1][zero + k + j] % 1000000007 * 2 %
               1000000007;
        ans %= 1000000007;
      }
      j = -vec[i - 1] + 1;
      for (long long(k) = (-m); (k) <= (m); (k)++) {
        if (k + j < -m || k + j > m) continue;
        ans += (long long)ldp[i - 1][zero + k] *
               (long long)rdp[i + 1][zero + k + j] % 1000000007 * 2 %
               1000000007;
        ans %= 1000000007;
      }
    }
  }
  cout << ans << endl;
  return 0;
}
