import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.BiFunction;
public class Main {
FastScanner sc = new FastScanner(System.in);
public static void main(String[] args) {
new Main().run();
}
int[][] ofs = {
{-1, 0},
{0, -1},
{0, 1},
{1, 0}
};
class Node {
int x, y, value;
Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
Node(Node n) {
this(n.x, n.y, n.value);
}
}
int h, w;
int[][] field;
long MOD = 1_000_000_007;
long[][] dp;
boolean[][] done;
void run() {
h = ni();
w = ni();
field = new int[h + 2][w + 2];
dp = new long[h + 2][w + 2];
done = new boolean[h + 2][w + 2];
PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> b.value - a.value);
for (int i = 1; i <= h; ++i) {
for (int j = 1; j <= w; ++j) {
field[i][j] = ni();
dp[i][j] = 1;
Node node = new Node(j, i, field[i][j]);
queue.add(node);
}
}
while (queue.size() > 0) {
Node atom = queue.poll();
for (int i = 0; i < 4; ++i) {
int nx = atom.x + ofs[i][0];
int ny = atom.y + ofs[i][1];
if (field[ny][nx] == 0) {
continue;
}
if (field[atom.y][atom.x] <= field[ny][nx]) {
continue;
}
dp[ny][nx] += dp[atom.y][atom.x];
dp[ny][nx] %= MOD;
}
done[atom.y][atom.x] = true;
}
long sum = 0;
for (int i = 1; i <= h; ++i) {
for (int j = 1; j <= w; ++j) {
sum += dp[i][j];
sum %= MOD;
}
}
System.out.println(sum);
}
int ni() {
return Integer.parseInt(sc.next());
}
void debug(Object... os) {
System.err.println(Arrays.deepToString(os));
}
class BIT<T> {
int n;
ArrayList<T> bit;
BiFunction<T, T, T> bif;
BIT(int n, BiFunction<T, T, T> bif, T defaultValue) {
this.n = n;
bit = new ArrayList<>(n + 1);
for (int i = 0; i < n + 1; ++i) {
bit.add(defaultValue);
}
this.bif = bif;
}
void update(int i, T v) {
for (int x = i; x <= n; x += x & -x) {
bit.set(x, bif.apply(bit.get(x), v));
}
}
T reduce(int i, T defaultValue) {
T ret = defaultValue;
for (int x = i; x > 0; x -= x & -x) {
ret = bif.apply(ret, bit.get(x));
}
return ret;
}
}
class FastScanner {
private final InputStream in;
private final byte[] buffer = new byte[1024];
private int ptr = 0;
private int buflen = 0;
FastScanner(InputStream in) {
this.in = in;
}
private boolean hasNextByte() {
if (ptr < buflen) {
return true;
} else {
ptr = 0;
try {
buflen = in.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
if (buflen <= 0) {
return false;
}
}
return true;
}
private int readByte() {
if (hasNextByte()) return buffer[ptr++];
else return -1;
}
private boolean isPrintableChar(int c) {
return 33 <= c && c <= 126;
}
private void skipUnprintable() {
while (hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;
}
public boolean hasNext() {
skipUnprintable();
return hasNextByte();
}
public String next() {
if (!hasNext()) throw new NoSuchElementException();
StringBuilder sb = new StringBuilder();
int b = readByte();
while (isPrintableChar(b)) {
sb.appendCodePoint(b);
b = readByte();
}
return sb.toString();
}
public long nextLong() {
if (!hasNext()) throw new NoSuchElementException();
long n = 0;
boolean minus = false;
int b = readByte();
if (b == '-') {
minus = true;
b = readByte();
}
if (b < '0' || '9' < b) {
throw new NumberFormatException();
}
while (true) {
if ('0' <= b && b <= '9') {
n *= 10;
n += b - '0';
} else if (b == -1 || !isPrintableChar(b)) {
return minus ? -n : n;
} else {
throw new NumberFormatException();
}
b = readByte();
}
}
int ni() {
return (int) nextLong();
}
}
}