#include <bits/stdc++.h>
namespace mem {
namespace stdval {
using i32 = int;
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using f32 = float;
using f64 = double;
using i128 = __int128_t;
using u128 = __uint128_t;
}  // namespace stdval
namespace io {
inline int getc() { return getchar(); }
inline void putc(int c) { putchar(c); }
template <class T>
inline void readDigit(T &x) {
  x = getc();
  while (!isdigit(x)) x = getc();
}
inline int readDigit() {
  int x;
  readDigit(x);
  return x;
}
template <class T>
inline void readAlpha(T &x) {
  x = getc();
  while (!isalpha(x)) x = getc();
}
inline int readAlpha() {
  int x;
  readAlpha(x);
  return x;
}
template <class T>
inline void readInt(T &x) {
  x = 0;
  bool f = 0;
  char c = getc();
  while (!isdigit(c)) f ^= c == '-', c = getc();
  while (isdigit(c)) x = x * 10 + c - '0', c = getc();
  if (f) x = -x;
}
inline void read(int &x) {
  x = 0;
  bool f = 0;
  char c = getchar();
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
inline void read(unsigned int &x) {
  x = 0;
  bool f = 0;
  char c = getchar();
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
inline void read(long long &x) {
  x = 0;
  bool f = 0;
  char c = getchar();
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
inline void read(unsigned long long &x) {
  x = 0;
  bool f = 0;
  char c = getchar();
  while (!isdigit(c)) f ^= c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
inline void read(char &x) { x = getc(); }
template <class T>
inline T read() {
  T x;
  read(x);
  return x;
}
template <class T, class... Args>
inline void read(T &x, Args &...args) {
  read(x), read(args...);
}
inline void print(int x) {
  if (x < 0) putc('-'), x = -x;
  if (x > 9) print(x / 10);
  putc('0' + x % 10);
}
inline void print(unsigned int x) {
  if (x < 0) putc('-'), x = -x;
  if (x > 9) print(x / 10);
  putc('0' + x % 10);
}
inline void print(long long x) {
  if (x < 0) putc('-'), x = -x;
  if (x > 9) print(x / 10);
  putc('0' + x % 10);
}
inline void print(unsigned long long x) {
  if (x < 0) putc('-'), x = -x;
  if (x > 9) print(x / 10);
  putc('0' + x % 10);
}
inline void print(char x) { putc(x); }
inline void print(const char *s) {
  int len = strlen(s);
  for (int i = 0; i < len; i++) putc(s[i]);
}
inline void print(const std::string &s) {
  for (int i = 0; i < s.length(); i++) putc(s[i]);
}
template <class T, class... Args>
inline void print(const T &x, Args... args) {
  print(x), print(args...);
}
template <class... Args>
inline void println(Args... args) {
  print(args...), putchar('\n');
}
}  // namespace io
namespace random {
const int LuckyNumber = 20040725;
std::mt19937 rng(LuckyNumber ^
                 std::chrono::steady_clock::now().time_since_epoch().count());
std::mt19937_64 rng64(
    LuckyNumber ^ std::chrono::steady_clock::now().time_since_epoch().count());
template <class T>
inline T rand(T l, T r) {
  return std::uniform_int_distribution<T>(l, r)(rng);
}
template <class T>
inline T rand64(T l, T r) {
  return std::uniform_int_distribution<T>(l, r)(rng);
}
}  // namespace random
namespace modint {
template <const int mod>
struct Z {
  int x;
  inline Z() { x = 0; }
  inline Z(int t) { x = t; }
  inline void operator-=(Z a) { (x -= a.x) < 0 && (x += mod); }
  inline void operator+=(Z a) { (x += a.x) >= mod && (x -= mod); }
  inline void operator*=(Z a) { x = (long long)x * a.x % mod; }
  friend inline Z operator*(Z a, Z b) { return (long long)a.x * b.x % mod; }
  friend inline Z operator-(Z a, Z b) {
    return ((a.x -= b.x) < 0 && (a.x += mod)), a;
  }
  friend inline Z operator+(Z a, Z b) {
    return ((a.x += b.x) >= mod && (a.x -= mod)), a;
  }
};
template <const int mod>
inline Z<mod> finv(Z<mod> x) {
  if (x.x < 2) return x;
  return (mod - mod / x.x) * finv(mod % x.x);
}
template <const int mod>
inline Z<mod> fpow(Z<mod> a, int b) {
  Z<mod> s = 1;
  for (; b; b >>= 1, a = a * a)
    if (b & 1) s = s * a;
  return s;
}
template <const int mod>
inline void init_inverse(int n, Z<mod> *inv) {
  inv[0] = inv[1] = 1;
  for (int i = 2; i < n; i++) inv[i] = (mod - mod / i) * inv[mod % i];
}
template <const int mod>
inline void init_factorial(int n, Z<mod> *fac, Z<mod> *ifac) {
  fac[0] = 1, init_inverse(n, ifac);
  for (int i = 1; i < n; i++)
    fac[i] = fac[i - 1] * i, ifac[i] = ifac[i - 1] * ifac[i];
}
}  // namespace modint
namespace math {
using namespace stdval;
template <class T>
inline T gcd(T n, T m) {
  return m ? gcd(m, n % m) : n;
}
template <class T>
inline T lcm(T n, T m) {
  return n / gcd(n, m) * m;
}
template <const u64 p>
struct FastDiv {
  u64 t, i;
  inline FastDiv() : t(u64(-1) / p), i(mul_inv(p)) {}
  inline bool divide(u64 n) { return n * i <= t; }
  inline bool divide(i64 n) { return u64(n < 0 ? -n : n) * i <= t; }
  inline u64 mul_inv(u64 n) {
    u64 x = n;
    for (int i = 0; i < 5; ++i) x *= 2 - n * x;
    return x;
  }
};
template <const u64 b>
struct FastMod {
  u64 m;
  FastMod() : m(u64((u128(1) << 64) / b)) {}
  u64 reduce(u64 a) {
    u64 q = (u64)((u128(m) * a) >> 64);
    u64 r = a - q * b;
    return r >= b ? r - b : r;
  }
};
}  // namespace math
using namespace io;
using namespace math;
using namespace modint;
using namespace random;
using namespace stdval;
}  // namespace mem
const int N = 4e3 + 10, mod = 1e9 + 7;
using z = mem::Z<mod>;
using std::vector;
using namespace mem::io;
using namespace mem::random;
int n, m;
bool vis[N];
z ans, sum, dp[N << 1], tmp[N << 1], cur[N << 1];
vector<int> cir, G[N];
int dfs(int u) {
  int res = 1;
  vis[u] = true;
  for (int v : G[u])
    if (!vis[v]) {
      res += dfs(v);
    }
  return res;
}
void choadd(z *a, z *b, int x) {
  memset(b, 0, N << 3);
  for (int i = -m; i <= m; i++) {
    if (i + x <= m) b[i + x + N] += a[i + N];
    if (i - x >= -m) b[i - x + N] += a[i + N];
  }
}
void chodel(z *a, z *b, int x) {
  for (int i = m; i >= -m; i--) {
    b[N + i] = i + x <= m ? a[N + i + x] : 0;
    if (i + x <= m) a[N + i + x] -= b[N + i];
    if (i - x >= -m) a[N + i - x] -= b[N + i];
  }
}
void add(z *a, z *b, int x) {
  memcpy(b, a, N << 3);
  for (int i = -m; i <= m; i++) {
    if (i + x <= m) b[i + x + N] += a[i + N];
    if (i - x >= -m) b[i - x + N] += a[i + N];
  }
}
void del(z *a, z *b, int x) {
  for (int i = m; i >= -m; i--) {
    b[N + i] = i + x <= m ? a[N + i + x] : 0;
    if (i + x <= m) a[N + i + x] -= b[N + i];
    a[N + i] -= b[N + i];
    if (i - x >= -m) a[N + i - x] -= b[N + i];
  }
}
int main() {
  read(n, m);
  for (int u, v, i = 1; i <= m; i++) {
    read(u, v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  vis[1] = true;
  for (int v : G[1])
    if (!vis[v]) {
      cir.push_back(dfs(v) + 1);
    }
  dp[0 + N] = 1;
  for (int x : cir) memcpy(tmp, dp, N << 3), choadd(tmp, dp, x);
  ans = dp[0 + N];
  for (int x : cir) {
    memcpy(tmp, dp, N << 3), chodel(tmp, cur, x);
    ans += cur[N + (x - 1)] * 2;
    ans += cur[N - (x - 1)] * 2;
  }
  memset(dp, 0, N << 3);
  dp[0 + N] = 1;
  for (int x : cir) memcpy(tmp, dp, N << 3), add(tmp, dp, x);
  for (int x : cir) {
    memcpy(tmp, dp, N << 3), del(tmp, cur, x);
    for (int i = 1; i < x; i++) {
      ans += cur[N + i - (x - i)] * 2;
    }
    for (int i = 1; i < x - 1; i++) {
      ans += cur[N + i - (x - 1 - i)] * 2;
    }
  }
  print(ans.x, '\n');
}
