There are n lights aligned in a row. These lights are numbered 1 to n from left to right. Initially some of the lights are switched on. Shaass wants to switch all the lights on. At each step he can switch a light on (this light should be switched off at that moment) if there's at least one adjacent light which is already switched on. 

He knows the initial state of lights and he's wondering how many different ways there exist to switch all the lights on. Please find the required number of ways modulo 1000000007 (109 + 7).

Input

The first line of the input contains two integers n and m where n is the number of lights in the sequence and m is the number of lights which are initially switched on, (1 ≤ n ≤ 1000, 1 ≤ m ≤ n). The second line contains m distinct integers, each between 1 to n inclusive, denoting the indices of lights which are initially switched on.

Output

In the only line of the output print the number of different possible ways to switch on all the lights modulo 1000000007 (109 + 7).

Examples

Input

3 1
1


Output

1


Input

4 2
1 4


Output

2


Input

11 2
4 8


Output

6720

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;
import java.util.StringTokenizer;

/**
 * @author Polyarniy Nickolay
 */
public class ProblemC {
    
    private BufferedReader in;
    private PrintWriter out;
    private StringTokenizer tok;
    private final String DELIMETER = " ";
    private final boolean ENABLE_MULTITEST = false;
    private final boolean DEBUG = true;
    private final String FILENAME = null;//if FILENAME = null, then works with console

    public void run() throws Exception {
        initInputOutput();
        do {
            init();
            solve();
        } while (hasMoreTokens() && ENABLE_MULTITEST);
        finish();
    }
    
    private void init() throws Exception {
    }
    
    private void solve() throws Exception {
        int n = nextInt();
        int m = nextInt();
        int[] a = nextArrayInt(m);
        Arrays.sort(a);
        long res = 1;
        long MOD = 1000000007l;
        long sum = 0;
        ArrayList<Integer> ai = new ArrayList<Integer>();
        for (int i = 1; i < m; i++) {
            int start = a[i - 1] + 1;
            for (int j = start; j < a[i] - 1; j++) {
                res = (res * 2) % MOD;
            }
            for (int j = start; j < a[i]; j++) {
                sum++;
                ai.add(j - start + 1);
            }
        }
        for (int i = a[m - 1] + 1; i <= n; i++) {
            ai.add(i - a[m - 1]);
            sum++;
        }
        for (int i = 1; i < a[0]; i++) {
            ai.add(i);
            sum++;
        }
//        out.println(ai.toString());
//        out.println(res);
        int[] aiI = new int[ai.size()];
        for (int i = 0; i < ai.size(); i++) {
            aiI[i] = ai.get(i);
        }
//        out.println(Arrays.toString(aiI));
        for (int i = 1; i <= sum; i++) {
            int mult = i;
            for (int j = 0; j < aiI.length; j++) {
                int cur = aiI[j];
                long nod = nod(cur, mult);
                if (nod != 1) {
                    mult /= nod;
                    aiI[j] /= nod;
                }
            }
            res = (res * mult) % MOD;
        }
//        out.println(Arrays.toString(aiI));
        out.println(res);
    }
    
    long nod(long a, long b) {
//        out.println("nod "+a+" "+b);
        out.flush();
        if (a == b) {
            return a;
        }
        if (a < b) {
            return nod(b, a);
        }
        if (a % b == 0) {
            return b;
        }
        return nod(a % b, b);
    }
    
    public static void main(String[] args) throws Exception {
        ProblemC solution = new ProblemC();
        solution.run();
    }
    
    private void initInputOutput() throws Exception {
        if (FILENAME == null) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        } else {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        }
    }
    
    private void shuffleArray(Object[] arr) {
        Random r = new Random();
        for (int i = 0; i < arr.length; ++i) {
            Object tmp = arr[i];
            int j = r.nextInt(arr.length);
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
    
    private void shuffleArray(int[] arr) {
        Random r = new Random();
        for (int i = 0; i < arr.length; ++i) {
            int tmp = arr[i];
            int j = r.nextInt(arr.length);
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
    
    private int[] nextArrayInt(int n) throws Exception {
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = nextInt();
        }
        return res;
    }
    
    private String nextWord() throws Exception {
        if (updateTokenizer()) {
            return null;
        } else {
            return tok.nextToken();
        }
    }
    
    private boolean hasMoreTokens() throws Exception {
        return !updateTokenizer();
    }
    
    private boolean updateTokenizer() throws Exception {
        while (tok == null || !tok.hasMoreTokens()) {
            String nextLine = in.readLine();
            if (nextLine == null || nextLine.isEmpty()) {
                return true;
            }
            tok = new StringTokenizer(nextLine, DELIMETER);
        }
        return false;
    }
    
    private int nextInt() throws Exception {
        return Integer.parseInt(nextWord());
    }
    
    private long nextLong() throws Exception {
        return Long.parseLong(nextWord());
    }
    
    private void finish() throws Exception {
        in.close();
        out.close();
    }
    
    private void print(String s) {
        if (DEBUG) {
            System.out.print(s);
        }
    }
    
    private void println(String s) {
        if (DEBUG) {
            System.out.println(s);
        }
    }
    
    private void println() {
        if (DEBUG) {
            System.out.println();
        }
    }
    
    private long[] getFirstSimpleNums(int n) {
        boolean[] notPr = new boolean[n];
        int res = n;
        notPr[0] = true;
        res--;
        notPr[1] = true;
        res--;
        for (int i = 2; i < n; ++i) {
            if (!notPr[i]) {
                for (int j = i + i; j < n; j += i) {
                    if (!notPr[j]) {
                        notPr[j] = true;
                        res--;
                    }
                }
            }
        }
        long[] resA = new long[res];
        int next = 0;
        for (int i = 0; i < n; i++) {
            if (!notPr[i]) {
                resA[next] = i;
                next++;
            }
        }
        return resA;
    }
    
    private static class Pair {
        
        int a;
        int b;
        
        public Pair(int a, int b) {
            this.a = a;
            this.b = b;
        }
        public static final Comparator<Pair> comparator = new Comparator<Pair>() {
            
            @Override
            public int compare(Pair pair1, Pair pair2) {
                return (pair1.a - pair2.a) != 0 ? (pair1.a - pair2.a) : (pair1.b - pair2.b);
            }
        };
        
        @Override
        public String toString() {
            return "{" + a + "|" + b + '}';
        }
    }
    
    class TreeMin {
        
        int n;
        int[] t;
        
        public TreeMin(int size, int[] defaultValue) {
            n = 1;
            while (n < size) {
                n *= 2;
            }
            t = new int[2 * n];
            for (int i = 0; i < defaultValue.length; i++) {
                t[n + i] = defaultValue[i];
            }
            for (int i = defaultValue.length; i < n; i++) {
                t[n + i] = Integer.MAX_VALUE;
            }
            for (int i = n - 1; i >= 1; i--) {
                t[i] = Math.min(t[2 * i], t[2 * i + 1]);
            }
        }
        
        public void set(int index, int value) {
            index += n;
            t[index] = value;
            index /= 2;
            while (index >= 1) {
                t[index] = Math.min(t[2 * index], t[2 * index + 1]);
                index /= 2;
            }
        }

        /**
         * @param l inclusive
         * @param r exclusive
         */
        public int getMin(int l, int r) {
            int min = Integer.MAX_VALUE;
            l += n;
            r += n;
            while (l <= r) {
                if (l % 2 == 1) {
                    min = Math.min(min, t[l]);
                    l++;
                }
                if (r % 2 == 0) {
                    min = Math.min(min, t[r]);
                    r--;
                }
                l /= 2;
                r /= 2;
            }
            return min;
        }
    }
    
    class PriorityQueue {
        
        int size = 0;
        int capacity = 5;
        int[] key = new int[capacity];
        int[] value = new int[capacity];
        int[] idByInd = new int[capacity];
        int nextID = 0;
        ArrayList<Integer> indById = new ArrayList<Integer>();
        
        void ensureCapacity(int newSize) {
            if (newSize > capacity) {
                key = increaseArray(key);
                value = increaseArray(value);
                idByInd = increaseArray(idByInd);
                capacity = key.length;
            }
        }
        
        int[] increaseArray(int[] a) {
            int[] res = new int[Math.max(a.length * 2, 1)];
            for (int i = 0; i < a.length; i++) {
                res[i] = a[i];
            }
            for (int i = a.length; i < res.length; i++) {
                res[i] = Integer.MAX_VALUE;
            }
            return res;
        }
        
        void swap(int ind1, int ind2) {
            swap(key, ind1, ind2);
            swap(value, ind1, ind2);
            int id1 = idByInd[ind1];
            int id2 = idByInd[ind2];
            swap(idByInd, ind1, ind2);
            swap(indById, id1, id2);
        }
        
        void swap(int[] a, int ind1, int ind2) {
            int tmp = a[ind1];
            a[ind1] = a[ind2];
            a[ind2] = tmp;
        }
        
        void swap(ArrayList<Integer> a, int ind1, int ind2) {
            int tmp = a.get(ind1);
            a.set(ind1, a.get(ind2));
            a.set(ind2, tmp);
        }
        
        int parent(int index) {
            return (index - 1) / 2;
        }
        
        private void siftUp(int index) {
            while (index > 0) {
                int parent = parent(index);
                if (key[index] < key[parent]) {
                    swap(index, parent);
                }
                index = parent;
            }
        }
        
        private void siftDown(int index) {
            while (true) {
                int ch1 = 2 * index + 1;
                int ch2 = 2 * index + 2;
                if (ch1 >= size) {
                    ch1 = index;
                }
                if (ch2 >= size) {
                    ch2 = ch1;
                }
                int toSwap = index;
                if (key[ch1] < key[toSwap]) {
                    toSwap = ch1;
                }
                if (key[ch2] < key[toSwap]) {
                    toSwap = ch2;
                }
                if (toSwap == index) {
                    break;
                } else {
                    swap(index, toSwap);
                    index = toSwap;
                }
            }
        }
        
        public int push(int key, int value) {
            size++;
            ensureCapacity(size);
            int id = nextID;
            nextID++;
            this.key[size - 1] = key;
            this.value[size - 1] = value;
            this.idByInd[size - 1] = id;
            indById.add(size - 1);
            siftUp(size - 1);
            return id;
        }
        
        public void decreaseKey(int id, int key) {
            int ind = indById.get(id);
            while (key > this.key[ind]) {
            }
            this.key[ind] = key;
            siftUp(ind);
        }
        public final int EMPTY = Integer.MIN_VALUE;
        
        public int extractMinKey() {
            if (size == 0) {
                return EMPTY;
            } else {
                int res = key[0];
                swap(0, size - 1);
                size--;
                siftDown(0);
                return res;
            }
        }
//        public String toString() {
//            String res = "{" + "size=" + size + "|k,v|";
//            for (int i = 0; i < size; i++) {
//                res += key[i]+"("+idByInd[i]+") ";// + "," + value[i];
//            }
//            res += "}";
//            return res;
//        }
    }
//    /**
//     * Examples(n: res):
//     * 0: 0
//     * 1: 0
//     * 2: 1
//     * 3: 2
//     * 4: 2
//     * 5: 3
//     * 7: 3
//     * 8: 3
//     * 10:4
//     */
//    public static int logCeil(int n) {
//        int res = 0;
//        int pow = 1;
//        while (pow < n) {
//            pow *= 2;
//            res++;
//        }
//        return res;
//    }
//
//    private static class Tree<T> {
//
//        Object[] t;
//        Object[] push;
//        int n;
//        int capacity;
//        TreeType<T> tree;
//
//        public Tree(int capacity, T[] a, TreeType<T> tree) {
//            this.tree = tree;
//            n = 1;
//            while (n < capacity) {
//                n *= 2;
//            }
//            t = new Object[2 * n];
//            push = new Object[n];
//            this.capacity = capacity;
//            System.arraycopy(a, 0, t, n, capacity);
//            for (int i = n - 1; i >= 1; i--) {
//                t[i] = tree.calc((T) t[i * 2], (T) t[i * 2 + 1]);
//            }
//        }
//
//        public T getOnRange(int l, int r) {
//            l += n;
//            r += n;
//            return getOnRange(l, r, 1, n, 2 * n - 1);
//        }
//
//        public T getOnRange(int l, int r, int cur, int rl, int rr) {
//            if (cur >= n) {
//                return (T) t[cur];
//            }
//            push(cur);
//            if (l == rl && r == rr) {
//                return (T) t[cur];
//            }
//            int m = (rl + rr) / 2;
//            T res = null;
//            if (l <= m) {
//                res = tree.sum(res, getOnRange(l, Math.min(m, r), 2 * cur, rl, m));
//            }
//            if (r >= m + 1) {
//                res = tree.sum(res, getOnRange(Math.max(m + 1, l), r, 2 * cur + 1, m + 1, rr));
//            }
//            return res;
//        }
//
//        public T get(int ind) {
//            int cur = 1;
//            int rl = n;
//            int rr = 2 * n - 1;
//            while (cur < n) {
//                push(cur);
//                int m = (rl + rr) / 2;
//                if (ind <= m) {
//                    cur = 2 * ind;
//                    rr = m;
//                } else {
//                    cur = 2 * ind + 1;
//                    rl = m + 1;
//                }
//            }
//            return (T) t[cur];
//        }
//
//        public void add(T x, int ind) {
//            int cur = 1;
//            int rl = n;
//            int rr = 2 * n - 1;
//            while (cur < n) {
//                push(cur);
//                int m = (rl + rr) / 2;
//                if (ind <= m) {
//                    cur = 2 * ind;
//                    rr = m;
//                } else {
//                    cur = 2 * ind + 1;
//                    rl = m + 1;
//                }
//            }
//            t[cur] = tree.calc((T) t[cur], x);
//        }
//
//        private void push(int cur) {
//            if (!tree.isEmpty((T) push[cur])) {
//                for (int ch = 0; ch <= 1; ch++) {
//                    if (2 * cur + ch < n) {
//                        push[2 * cur + ch] = tree.calc((T)push[2 * cur + ch], (T)push[cur]);
//                    } else {
//                        t[2 * cur + ch] = tree.calc((T)t[2 * cur + ch], (T)push[cur]);
//                    }
//                }
//                push[cur] = null;
//            }
//        }
//    }
//
//    private static interface TreeType<T> {
//
//        public T calc(T a, T b);
//
//        public boolean isEmpty(T push);
//    }
}
