You are given an integer m.

Let M = 2m - 1.

You are also given a set of n integers denoted as the set T. The integers will be provided in base 2 as n binary strings of length m.

A set of integers S is called "good" if the following hold. 

  1. If <image>, then <image>. 
  2. If <image>, then <image>
  3. <image>
  4. All elements of S are less than or equal to M. 



Here, <image> and <image> refer to the bitwise XOR and bitwise AND operators, respectively.

Count the number of good sets S, modulo 109 + 7.

Input

The first line will contain two integers m and n (1 ≤ m ≤ 1 000, 1 ≤ n ≤ min(2m, 50)).

The next n lines will contain the elements of T. Each line will contain exactly m zeros and ones. Elements of T will be distinct.

Output

Print a single integer, the number of good sets modulo 109 + 7. 

Examples

Input

5 3
11010
00101
11000


Output

4


Input

30 2
010101010101010010101010101010
110110110110110011011011011011


Output

860616440

Note

An example of a valid set S is {00000, 00101, 00010, 00111, 11000, 11010, 11101, 11111}.
#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct Z_p {
  using Type = typename decay<decltype(T::value)>::type;
  static vector<Type> mod_inv;
  constexpr Z_p() : value() {}
  template <typename U>
  Z_p(const U &x) {
    value = normalize(x);
  }
  template <typename U>
  static Type normalize(const U &x) {
    Type v;
    if (-mod() <= x && x < mod())
      v = static_cast<Type>(x);
    else
      v = static_cast<Type>(x % mod());
    if (v < 0) v += mod();
    return v;
  }
  const Type &operator()() const { return value; }
  template <typename U>
  explicit operator U() const {
    return static_cast<U>(value);
  }
  constexpr static Type mod() { return T::value; }
  Z_p &operator+=(const Z_p &otr) {
    if ((value += otr.value) >= mod()) value -= mod();
    return *this;
  }
  Z_p &operator-=(const Z_p &otr) {
    if ((value -= otr.value) < 0) value += mod();
    return *this;
  }
  template <typename U>
  Z_p &operator+=(const U &otr) {
    return *this += Z_p(otr);
  }
  template <typename U>
  Z_p &operator-=(const U &otr) {
    return *this -= Z_p(otr);
  }
  Z_p &operator++() { return *this += 1; }
  Z_p &operator--() { return *this -= 1; }
  Z_p operator++(int) {
    Z_p result(*this);
    *this += 1;
    return result;
  }
  Z_p operator--(int) {
    Z_p result(*this);
    *this -= 1;
    return result;
  }
  Z_p operator-() const { return Z_p(-value); }
  template <typename U = T>
  typename enable_if<is_same<typename Z_p<U>::Type, int>::value, Z_p>::type &
  operator*=(const Z_p &rhs) {
    value = normalize(static_cast<int64_t>(value) *
                      static_cast<int64_t>(rhs.value));
    return *this;
  }
  template <typename U = T>
  typename enable_if<is_same<typename Z_p<U>::Type, int64_t>::value, Z_p>::type
      &
      operator*=(const Z_p &rhs) {
    int64_t q = static_cast<int64_t>(static_cast<long double>(value) *
                                     rhs.value / mod());
    value = normalize(value * rhs.value - q * mod());
    return *this;
  }
  template <typename U = T>
  typename enable_if<!is_integral<typename Z_p<U>::Type>::value, Z_p>::type &
  operator*=(const Z_p &rhs) {
    value = normalize(value * rhs.value);
    return *this;
  }
  Z_p operator^(long long e) const {
    Z_p b = *this, res = 1;
    if (e < 0) b = 1 / b, e = -e;
    for (; e; b *= b, e >>= 1)
      if (e & 1) res *= b;
    return res;
  }
  Z_p &operator^=(const long long &e) { return *this = *this ^ e; }
  Z_p &operator/=(const Z_p &otr) {
    Type a = otr.value, m = mod(), u = 0, v = 1;
    if (a < int(mod_inv.size())) return *this *= mod_inv[a];
    while (a) {
      Type t = m / a;
      m -= t * a;
      swap(a, m);
      u -= t * v;
      swap(u, v);
    }
    assert(m == 1);
    return *this *= u;
  }
  template <typename U>
  friend const Z_p<U> &abs(const Z_p<U> &v) {
    return v;
  }
  Type value;
};
template <typename T>
bool operator==(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return lhs.value == rhs.value;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
bool operator==(const Z_p<T> &lhs, U rhs) {
  return lhs == Z_p<T>(rhs);
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
bool operator==(U lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) == rhs;
}
template <typename T>
bool operator!=(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return !(lhs == rhs);
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
bool operator!=(const Z_p<T> &lhs, U rhs) {
  return !(lhs == rhs);
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
bool operator!=(U lhs, const Z_p<T> &rhs) {
  return !(lhs == rhs);
}
template <typename T>
bool operator<(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return lhs.value < rhs.value;
}
template <typename T>
bool operator>(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return lhs.value > rhs.value;
}
template <typename T>
bool operator<=(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return lhs.value <= rhs.value;
}
template <typename T>
bool operator>=(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return lhs.value >= rhs.value;
}
template <typename T>
Z_p<T> operator+(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) += rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator+(const Z_p<T> &lhs, U rhs) {
  return Z_p<T>(lhs) += rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator+(U lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) += rhs;
}
template <typename T>
Z_p<T> operator-(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) -= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator-(const Z_p<T> &lhs, U rhs) {
  return Z_p<T>(lhs) -= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator-(U lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) -= rhs;
}
template <typename T>
Z_p<T> operator*(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) *= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator*(const Z_p<T> &lhs, U rhs) {
  return Z_p<T>(lhs) *= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator*(U lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) *= rhs;
}
template <typename T>
Z_p<T> operator/(const Z_p<T> &lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) /= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator/(const Z_p<T> &lhs, U rhs) {
  return Z_p<T>(lhs) /= rhs;
}
template <typename T, typename U,
          typename enable_if<is_integral<U>::value>::type * = nullptr>
Z_p<T> operator/(U lhs, const Z_p<T> &rhs) {
  return Z_p<T>(lhs) /= rhs;
}
template <typename T>
istream &operator>>(istream &in, Z_p<T> &number) {
  typename common_type<typename Z_p<T>::Type, int64_t>::type x;
  in >> x;
  number.value = Z_p<T>::normalize(x);
  return in;
}
template <typename T>
ostream &operator<<(ostream &out, const Z_p<T> &number) {
  return out << number();
}
constexpr int mod = 1e9 + 7;
using Zp = Z_p<integral_constant<decay<decltype(mod)>::type, mod>>;
template <typename T>
vector<typename Z_p<T>::Type> Z_p<T>::mod_inv;
template <typename T = integral_constant<decay<decltype(mod)>::type, mod>>
void precalc_inverse(size_t SZ) {
  auto &inv = Z_p<T>::mod_inv;
  if (inv.empty()) inv.assign(2, 1);
  for (; inv.size() <= SZ;)
    inv.push_back(
        (mod - 1LL * mod / (int)inv.size() * inv[mod % (int)inv.size()]) % mod);
}
template <typename T>
vector<T> precalc_power(T base, size_t SZ) {
  vector<T> res(SZ + 1, 1);
  for (int i = 1; i <= SZ; ++i) res[i] = res[i - 1] * base;
  return res;
}
template <class T>
struct combinatorics {
  int SZ;
  vector<T> inv, fact, invfact;
  vector<vector<T>> stir1, stir2;
  combinatorics(int SZ)
      : SZ(SZ), inv(SZ + 1, 1), fact(SZ + 1, 1), invfact(SZ + 1, 1) {
    for (int i = 1; i <= SZ; ++i) fact[i] = fact[i - 1] * i;
    invfact[SZ] = 1 / fact[SZ];
    for (int i = SZ - 1; i >= 0; --i) {
      invfact[i] = invfact[i + 1] * (i + 1);
      inv[i + 1] = invfact[i + 1] * fact[i];
    }
  }
  T C(int n, int k) {
    return n < 0            ? C(-n + k - 1, k) * (k & 1 ? -1 : 1)
           : n < k || k < 0 ? 0
                            : fact[n] * invfact[k] * invfact[n - k];
  }
  T P(int n, int k) { return n < k ? 0 : fact[n] * invfact[n - k]; }
  T H(int n, int k) { return C(n + k - 1, k); }
  T naive_C(long long n, long long k) {
    if (n < k) return 0;
    T res = 1;
    k = min(k, n - k);
    for (long long i = n; i > n - k; --i) res *= i;
    return res * invfact[k];
  }
  T naive_P(long long n, int k) {
    if (n < k) return 0;
    T res = 1;
    for (long long i = n; i > n - k; --i) res *= i;
    return res;
  }
  T naive_H(long long n, long long k) { return naive_C(n + k - 1, k); }
  bool parity_C(long long n, long long k) { return n < k ? 0 : k & n - k ^ 1; }
  T Cat(int n, int k, int m = 1) {
    if (m <= 0)
      return 0;
    else if (k >= 0 && k < m)
      return C(n + k, k);
    else if (k < n + m)
      return C(n + k, k) - C(n + k, k - m);
    else
      return 0;
  }
  array<bool, 2> pre{};
  template <bool FIRST = true>
  void precalc_stir(int n, int k) {
    auto &s = FIRST ? stir1 : stir2;
    pre[!FIRST] = true;
    s.resize(n + 1, vector<T>(k + 1, 1));
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= k; ++j) {
        s[i][j] = (FIRST ? i - 1 : j) * s[i - 1][j] + s[i - 1][j - 1];
      }
  }
  T Stir1(int n, int k) {
    if (n < k) return 0;
    assert(pre[0]);
    return stir1[n][k];
  }
  T Stir2(long long n, int k) {
    if (n < k) return 0;
    if (pre[1] && n < (int)stir2.size()) return stir2[n][k];
    T res = 0;
    for (int i = 0, sign = 1; i <= k; ++i, sign *= -1)
      res += sign * C(k, i) * (Zp(k - i) ^ n);
    return res * invfact[k];
  }
  bool parity_Stir2(long long n, long long k) {
    return n < k ? 0 : k ? !(n - k & k - 1 >> 1) : 0;
  }
};
int main() {
  cin.tie(0)->sync_with_stdio(0);
  cin.exceptions(ios::badbit | ios::failbit);
  int m, n;
  cin >> m >> n;
  combinatorics<Zp> C(m);
  vector<string> T(n);
  for (auto i = 0; i < n; ++i) {
    cin >> T[i];
  }
  map<vector<int>, int> cnt;
  for (auto i = 0; i < m; ++i) {
    vector<int> state;
    for (auto j = 0; j < n; ++j) {
      state.push_back(T[j][i] - '0');
    }
    ++cnt[state];
  }
  vector<Zp> dp(m + 1);
  dp[0] = dp[1] = 1;
  for (auto i = 2; i <= m; ++i) {
    for (auto j = 1; j <= i; ++j) {
      dp[i] += C.C(i - 1, j - 1) * dp[i - j];
    }
  }
  Zp res = 1;
  for (auto [ignore, x] : cnt) {
    res *= dp[x];
  }
  cout << res << "\n";
  return 0;
}
