One day little Vasya found mom's pocket book. The book had n names of her friends and unusually enough, each name was exactly m letters long. Let's number the names from 1 to n in the order in which they are written.

As mom wasn't home, Vasya decided to play with names: he chose three integers i, j, k (1 ≤ i < j ≤ n, 1 ≤ k ≤ m), then he took names number i and j and swapped their prefixes of length k. For example, if we take names "CBDAD" and "AABRD" and swap their prefixes with the length of 3, the result will be names "AABAD" and "CBDRD".

You wonder how many different names Vasya can write instead of name number 1, if Vasya is allowed to perform any number of the described actions. As Vasya performs each action, he chooses numbers i, j, k independently from the previous moves and his choice is based entirely on his will. The sought number can be very large, so you should only find it modulo 1000000007 (109 + 7).

Input

The first input line contains two integers n and m (1 ≤ n, m ≤ 100) — the number of names and the length of each name, correspondingly. Then n lines contain names, each name consists of exactly m uppercase Latin letters.

Output

Print the single number — the number of different names that could end up in position number 1 in the pocket book after the applying the procedures described above. Print the number modulo 1000000007 (109 + 7).

Examples

Input

2 3
AAB
BAA


Output

4


Input

4 5
ABABA
BCGDG
AAAAA
YABSA


Output

216

Note

In the first sample Vasya can get the following names in the position number 1: "AAB", "AAA", "BAA" and "BAB".
/*
    Aman Agarwal
    algo.java
*/

import java.util.*;
import java.io.*;

public class C152
{
    static class FastReader
    {
            BufferedReader br;
            StringTokenizer st;

            public FastReader()
            {
                br = new BufferedReader(new InputStreamReader(System.in));
            }

            String next()
            {
                while (st == null || !st.hasMoreElements())
                {
                    try
                    {
                        st = new StringTokenizer(br.readLine());
                    }
                    catch (IOException  e)
                    {
                        e.printStackTrace();
                    }
                }
                return st.nextToken();
            }

            int nextInt()
            {
                return Integer.parseInt(next());
            }

            long nextLong()
            {
                return Long.parseLong(next());
            }

            double nextDouble()
            {
                return Double.parseDouble(next());
            }

            String nextLine()
            {
                String str = "";
                try
                {
                    str = br.readLine();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                return str;
            }
    }


    static FastReader sc = new FastReader();
    static PrintWriter out = new PrintWriter(System.out);
    static int ni()throws IOException{return sc.nextInt();}
    static long nl()throws IOException{return sc.nextLong();}
    static int[][] nai2(int n,int m)throws IOException{int a[][] = new int[n][m];for(int i=0;i<n;i++)for(int j=0;j<m;j++)a[i][j] = ni();return a;}
    static int[] nai(int N,int start)throws IOException{int[]A=new int[N+start];for(int i=start;i!=(N+start);i++){A[i]=ni();}return A;}
    static Integer[] naI(int N,int start)throws IOException{Integer[]A=new Integer[N+start];for(int i=start;i!=(N+start);i++){A[i]=ni();}return A;}
    static long[] nal(int N)throws IOException{long[]A=new long[N];for(int i=0;i!=N;i++){A[i]=nl();}return A;}
    static char[] nac()throws IOException{char[]A=sc.next().toCharArray();return A;}
    static void print(int arr[]){for(int i=0;i<arr.length;i++)out.print(arr[i]+" ");out.println();}
    static void print(long arr[]){for(int i=0;i<arr.length;i++)out.print(arr[i]+" ");out.println();}
    static long gcd(long a, long b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int gcd(int a, int b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int bit(long n)throws IOException{return (n==0)?0:(1+bit(n&(n-1)));} // return the number of set bits.
    static boolean isPrime(int number){if(number==1) return false;if (number == 2 || number == 3){return true;}if (number % 2 == 0) {return false;}int sqrt = (int) Math.sqrt(number) + 1;for(int i = 3; i < sqrt; i += 2){if (number % i == 0){return false;}}return true;}
    static boolean isPrime(long number){if(number==1) return false;if (number == 2 || number == 3){return true;}if (number % 2 == 0) {return false;}long sqrt = (long) Math.sqrt(number) + 1;for(int i = 3; i < sqrt; i += 2){if (number % i == 0){return false;}}return true;}
    static int power(int n,int p){if(p==0)return 1;int a = power(n,p/2);a = a*a;int b = p & 1;if(b!=0){a =  n*a;}return a;}
    static long power(long n,long p){if(p==0)return 1;long a = power(n,p/2);a = a*a;long b = p & 1;if(b!=0){a =  n*a;}return a;}
    static void reverse(int[] a) {int b;for (int i = 0, j = a.length - 1; i < j; i++, j--) {b = a[i];a[i] = a[j];a[j] = b;}}
    static void reverse(long[] a) {long b;for (int i = 0, j = a.length - 1; i < j; i++, j--) {b = a[i];a[i] = a[j];a[j] = b;}}
    static void swap(int a[],int i,int j){a[i] = a[i] ^ a[j];a[j] = a[j] ^ a[i];a[i] = a[i] ^ a[j];}
    static void swap(long a[],int i,int j){a[i] = a[i] ^ a[j];a[j] = a[j] ^ a[i];a[i] = a[i] ^ a[j];}
    static int count(int n){int c=0;while(n>0){c++;n = n/10;}return c;}
    static int[] prefix_sum(int a[],int n){int s[] = new int[n];s[0] = a[0];for(int i=1;i<n;i++){s[i] = a[i]+s[i-1];}return s;}
    static long[] prefix_sum_int(int a[],int n){long s[] = new long[n];s[0] = (long)a[0];for(int i=1;i<n;i++){s[i] = ((long)a[i])+s[i-1];}return s;}
    static long[] prefix_sum_Integer(Integer a[],int n){long s[] = new long[n];s[0] = (long)a[0];for(int i=1;i<n;i++){s[i] = ((long)a[i])+s[i-1];}return s;}
    static long[] prefix_sum_long(long a[],int n){long s[] = new long[n];s[0] = a[0];for(int i=1;i<n;i++){s[i] = a[i]+s[i-1];}return s;}
    static boolean isPerfectSquare(double x){double sr = Math.sqrt(x);return ((sr - Math.floor(sr)) == 0);}
    static ArrayList<Integer> sieve(int n) {int k=0; boolean prime[] = new boolean[n+1];ArrayList<Integer> p_arr = new ArrayList<>();for(int i=0;i<n;i++) prime[i] = true;for(int p = 2; p*p <=n; p++){ k=p;if(prime[p] == true) { p_arr.add(p);for(int i = p*2; i <= n; i += p) prime[i] = false; } }for(int i = k+1;i<=n;i++){if(prime[i]==true)p_arr.add(i);}return p_arr;} 
    static boolean[] seive_check(int n) {boolean prime[] = new boolean[n+1];for(int i=0;i<n;i++) prime[i] = true;for(int p = 2; p*p <=n; p++){ if(prime[p] == true) { for(int i = p*2; i <= n; i += p) prime[i] = false; } }prime[1]=false;return prime;} 
    static int get_bits(int n){int p=0;while(n>0){p++;n = n>>1;}return p;}
    static int get_bits(long n){int p=0;while(n>0){p++;n = n>>1;}return p;}
    static int get_2_power(int n){if((n & (n-1))==0)return get_bits(n)-1;return -1;}
    static int get_2_power(long n){if((n & (n-1))==0)return get_bits(n)-1;return -1;}
    static void close(){out.flush();}

    /*-------------------------Main Code Starts(algo.java)----------------------------------*/    

    public static void solve() throws IOException 
    {
        int n = ni();
        int m = ni();
        long ans=1;
        String s[] = new String[n];
        if(n==1)
        {
            s[0] = sc.next();
            out.println(1);
            return;
        }
        for(int i=0;i<n;i++)
            s[i] = sc.next();

        for(int i=0;i<m;i++)
        {
            Map<Character,Boolean> mp = new HashMap<>();
            int cnt=0;
            for(int j=0;j<n;j++)
            {
                if(!mp.containsKey(s[j].charAt(i)))
                {
                    mp.put(s[j].charAt(i),true);
                    cnt++;
                }
            }
            ans = (ans*cnt)%1000000007;
        }
        out.println(ans);
    }

    public static void main(String[] args) throws IOException 
    {
        int test = 1;
       // test = sc.nextInt();
        while(test-- > 0)
        {
            solve();
        }
        close();
    }
}
