#include <bits/stdc++.h>
using namespace std;
long long ways[ 1 << 16 ] ;
long long mod = 1000000007 ;
long long dp[ 17 ] [ 1 << 16 ] ;
int posCode[ 16 ] ;
int toMask[ 1 << 16 ] ;
class CampLunch
{
public :
int count( int N, int M, vector < string> a)
{
memset ( ways, 0 , sizeof ( ways) ) ;
for ( int mask = 0 ; mask < ( 1 << ( M- 1 ) ) ; mask ++ )
if ( ( mask & ( mask<< 1 ) ) == 0 )
{
int x = mask | ( mask << 1 ) ;
for ( int i = 0 ; i < ( 1 << M) ; i++ )
if ( ( x & i) == 0 )
ways[ i] ++ ;
}
memset ( dp, 0 , sizeof ( dp) ) ;
dp[ 0 ] [ 0 ] = 1 ;
for ( int i = 0 ; i < N; i++ )
{
for ( int j = 0 ; j < M; j++ )
{
posCode[ a[ i] [ j] - 'A' ] = ( 1 << j) ;
}
for ( int j = 0 ; j < ( 1 << M) ; j++ )
{
toMask[ j] = 0 ;
for ( int k = 0 ; k < M; k++ )
if ( ( j & ( 1 << k) ) > 0 )
{
toMask[ j] + = posCode[ k] ;
}
}
for ( int mask = 0 ; mask < ( 1 << M) ; mask ++ )
{
if ( dp[ i] [ mask] == 0 ) continue ;
dp[ i] [ mask] % = mod;
int remain = ( 1 << M) - 1 - mask;
for ( int take = remain; ; take = ( ( take- 1 ) & remain) )
{
dp[ i+ 1 ] [ take] + = dp[ i] [ mask] * ways[ toMask[ mask | take] ] ;
//dp[i+1][take] %= mod;
if ( take == 0 )
break ;
}
}
}
return dp[ N] [ 0 ] % mod;
}
} ;
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgpsb25nIGxvbmcgd2F5c1sxPDwxNl07CmxvbmcgbG9uZyBtb2QgPSAxMDAwMDAwMDA3OwoKbG9uZyBsb25nIGRwWzE3XVsxPDwxNl07CmludCBwb3NDb2RlWzE2XTsKaW50IHRvTWFza1sxPDwxNl07CgpjbGFzcyBDYW1wTHVuY2gKewoJcHVibGljOgoJaW50IGNvdW50KGludCBOLCBpbnQgTSwgdmVjdG9yIDxzdHJpbmc+IGEpCgl7CgkJbWVtc2V0KHdheXMsIDAsIHNpemVvZih3YXlzKSk7CgkJZm9yKGludCBtYXNrID0gMDsgbWFzayA8ICgxPDwoTS0xKSk7IG1hc2sgKyspCgkJCWlmKChtYXNrICYgKG1hc2s8PDEpKSA9PSAwKQoJCQl7CgkJCQlpbnQgeCA9IG1hc2sgfCAobWFzayA8PCAxKTsKCQkJCWZvcihpbnQgaSA9IDA7IGkgPCAoMTw8TSk7IGkrKykKCQkJCQlpZigoeCAmIGkpID09IDApCgkJCQkJCXdheXNbaV0gKys7CgkJCX0KCQltZW1zZXQoZHAsIDAsIHNpemVvZihkcCkpOwoJCWRwWzBdWzBdID0gMTsKCQlmb3IoaW50IGkgPSAwOyBpIDwgTjsgaSsrKQoJCXsKCQkJZm9yKGludCBqID0gMDsgaiA8IE07IGorKykKCQkJewoJCQkJcG9zQ29kZVthW2ldW2pdLSdBJ10gPSAoMTw8aik7IAoJCQl9CgkJCWZvcihpbnQgaiA9IDA7IGogPCAoMTw8TSk7IGorKykKCQkJewoJCQkJdG9NYXNrW2pdID0gMDsKCQkJCWZvcihpbnQgayA9IDA7IGsgPCBNOyBrKyspCgkJCQkJaWYoKGogJiAoMTw8aykpID4gMCkKCQkJCQl7CgkJCQkJCXRvTWFza1tqXSArPSBwb3NDb2RlW2tdOwoJCQkJCX0KCQkJfQoKCgkJCWZvcihpbnQgbWFzayA9IDA7IG1hc2sgPCAoMTw8TSk7IG1hc2sgKyspCgkJCXsKCQkJCWlmKGRwW2ldW21hc2tdID09IDApIGNvbnRpbnVlOwoJCQkJZHBbaV1bbWFza10gJT0gbW9kOwoJCQkJaW50IHJlbWFpbiA9ICgxPDxNKS0xIC0gbWFzazsKCQkJCWZvcihpbnQgdGFrZSA9IHJlbWFpbjsgOyB0YWtlID0gKCh0YWtlLTEpJnJlbWFpbikpCgkJCQl7CgkJCQkJZHBbaSsxXVt0YWtlXSArPSBkcFtpXVttYXNrXSAqIHdheXNbdG9NYXNrW21hc2sgfCB0YWtlXV07CgkJCQkJLy9kcFtpKzFdW3Rha2VdICU9IG1vZDsKCQkJCQlpZih0YWtlID09IDApCgkJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiBkcFtOXVswXSAlIG1vZDsKCX0KCn07Cg==