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;
double EPS = 1e-9;
int INF = 1000000005;
long long INFF = 1000000000000000005LL;
double PI = acos(-1);
int dirx[8] = {-1, 0, 0, 1, -1, -1, 1, 1};
int diry[8] = {0, 1, -1, 0, -1, 1, -1, 1};
inline string IntToString(long long a) {
  char x[100];
  sprintf(x, "%lld", a);
  string s = x;
  return s;
}
inline long long StringToInt(string a) {
  char x[100];
  long long res;
  strcpy(x, a.c_str());
  sscanf(x, "%lld", &res);
  return res;
}
inline string GetString(void) {
  char x[1000005];
  scanf("%s", x);
  string s = x;
  return s;
}
inline string uppercase(string s) {
  int n = (int)s.size();
  for (int(i) = (0); (i) < (n); ++(i))
    if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A';
  return s;
}
inline string lowercase(string s) {
  int n = (int)s.size();
  for (int(i) = (0); (i) < (n); ++(i))
    if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] - 'A' + 'a';
  return s;
}
inline void OPEN(string s) {
  freopen((s + ".in").c_str(), "r", stdin);
  freopen((s + ".out").c_str(), "w", stdout);
}
long long MOD = 1e9 + 7;
long long S[1005][1005];
long long jum[1005];
int n, m;
string data[55];
vector<int> ada;
bool aktif[1005];
long long jahja(int n, int k) {
  long long &ret = S[n][k];
  if (ret >= 0) return ret;
  if (n == 0 || k == 0 || k > n) return ret = 0;
  if (k == 1 || k == n) return ret = 1;
  return ret = (k * jahja(n - 1, k) + jahja(n - 1, k - 1)) % MOD;
}
int main() {
  memset(S, -1, sizeof(S));
  scanf("%d %d", &m, &n);
  for (int(i) = (0); (i) < (n); ++(i)) data[i] = GetString();
  memset(aktif, 1, sizeof(aktif));
  for (int(i) = (0); (i) < (m); ++(i)) {
    if (!aktif[i]) continue;
    int now = 1;
    for (int(j) = (i + 1); (j) < (m); ++(j))
      if (aktif[j]) {
        for (int(k) = (0); (k) < (n); ++(k))
          if (data[k][i] != data[k][j]) goto hell;
        ++now;
        aktif[j] = 0;
      hell:;
      }
    ada.push_back(now);
  }
  for (int(i) = (1); (i) <= (m); ++(i)) {
    for (int(j) = (1); (j) <= (i); ++(j)) jum[i] = (jum[i] + jahja(i, j)) % MOD;
  }
  long long risan = 1;
  for (int(i) = (0); (i) < ((int)ada.size()); ++(i))
    risan = (risan * jum[ada[i]]) % MOD;
  printf("%lld\n", risan);
}
