#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7, M = 2e6 + 7;
struct query {
  int u, v;
} e[M];
long long ans;
bool rev[M];
int n, m, tp, ts, cnt, pos, que[5], qut[5], w[N][N], st[M], lt[M], rt[M], ta[M],
    tb[M], tc[M], pot[M], lent[M], fa[M], ch[M][2];
inline int read() {
  int num = 0;
  char g = getchar();
  while (g < 48 || 57 < g) g = getchar();
  while (47 < g && g < 58)
    num = (num << 1) + (num << 3) + g - 48, g = getchar();
  return num;
}
inline void build(int l, int r, int t) {
  lt[t] = l, rt[t] = r, tb[t] = r - l + 1;
  if (l == r) return;
  int d = (l + r) >> 1;
  build(l, d, t << 1), build(d + 1, r, t << 1 | 1);
}
inline void addit(int l, int r, int t, int z) {
  ta[t << 1] += tc[t], ta[t << 1 | 1] += tc[t], tc[t << 1] += tc[t],
      tc[t << 1 | 1] += tc[t], tc[t] = 0;
  if (lt[t] == l && rt[t] == r) {
    tc[t] += z, ta[t] += z;
    return;
  }
  int d = (lt[t] + rt[t]) >> 1;
  if (l <= d) addit(l, min(d, r), t << 1, z);
  if (r > d) addit(max(d + 1, l), r, t << 1 | 1, z);
  if (ta[t << 1] < ta[t << 1 | 1])
    ta[t] = ta[t << 1], tb[t] = tb[t << 1];
  else if (ta[t << 1] > ta[t << 1 | 1])
    ta[t] = ta[t << 1 | 1], tb[t] = tb[t << 1 | 1];
  else
    ta[t] = ta[t << 1], tb[t] = tb[t << 1] + tb[t << 1 | 1];
}
inline void search(int l, int r, int t) {
  ta[t << 1] += tc[t], ta[t << 1 | 1] += tc[t], tc[t << 1] += tc[t],
      tc[t << 1 | 1] += tc[t], tc[t] = 0;
  if (lt[t] == l && rt[t] == r) {
    if (ta[t] == 1) ans += tb[t];
    return;
  }
  int d = (lt[t] + rt[t]) >> 1;
  if (l <= d) search(l, min(d, r), t << 1);
  if (r > d) search(max(d + 1, l), r, t << 1 | 1);
}
inline int calc(int x, int y) { return (x - 1) * m + y; }
inline bool isroot(int u) { return (ch[fa[u]][0] != u && ch[fa[u]][1] != u); }
inline bool get(int u) { return (ch[fa[u]][1] == u); }
inline void revit(int u) {
  if (rev[u])
    swap(ch[u][0], ch[u][1]), rev[ch[u][0]] ^= 1, rev[ch[u][1]] ^= 1,
        rev[u] ^= 1;
}
inline void rotate(int u) {
  int pa = fa[u], gr = fa[pa], x = get(u);
  if (!isroot(pa)) ch[gr][get(pa)] = u;
  fa[u] = gr;
  ch[pa][x] = ch[u][x ^ 1], fa[ch[u][x ^ 1]] = pa, ch[u][x ^ 1] = pa,
  fa[pa] = u;
}
inline void splay(int u) {
  st[st[0] = 1] = u;
  for (int x = u; !isroot(x); x = fa[x]) st[++st[0]] = fa[x];
  for (int x = st[0]; x > 0; x--) revit(st[x]);
  for (; !isroot(u); rotate(u))
    if (!isroot(fa[u])) rotate(get(fa[u]) == get(u) ? fa[u] : u);
}
inline void access(int u) {
  for (int i = 0; u > 0; i = u, u = fa[u]) splay(u), ch[u][1] = i;
}
inline void makeroot(int u) { access(u), splay(u), rev[u] ^= 1; }
inline void link(int u, int v) { makeroot(v), fa[v] = u; }
inline void cut(int u, int v) {
  makeroot(u), access(v), splay(v), fa[u] = 0, ch[v][0] = 0;
}
inline int find(int u) {
  access(u), splay(u);
  while (ch[u][0]) u = ch[u][0];
  return u;
}
int main() {
  n = read(), m = read(), build(1, n * m, 1), pos = n * m, tp = 1, ts = 1;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      w[i][j] = read(), e[w[i][j]].u = i, e[w[i][j]].v = j;
  while (tp <= n * m) {
    int px = e[tp].u, py = e[tp].v;
    que[0] = 0, qut[1] = -1, qut[2] = -2, qut[3] = -3, qut[4] = -4;
    if (w[px - 1][py] >= ts && w[px - 1][py] < tp)
      que[++que[0]] = calc(px - 1, py);
    if (w[px + 1][py] >= ts && w[px + 1][py] < tp)
      que[++que[0]] = calc(px + 1, py);
    if (w[px][py - 1] >= ts && w[px][py - 1] < tp)
      que[++que[0]] = calc(px, py - 1);
    if (w[px][py + 1] >= ts && w[px][py + 1] < tp)
      que[++que[0]] = calc(px, py + 1);
    for (int i = 1; i <= que[0]; i++) qut[i] = find(que[i]);
    if (qut[1] == qut[2] || qut[1] == qut[3] || qut[1] == qut[4] ||
        qut[2] == qut[3] || qut[2] == qut[4] || qut[3] == qut[4]) {
      pot[ts] = tp, que[0] = 0;
      int px = e[ts].u, py = e[ts].v;
      if (w[px - 1][py] >= ts && w[px - 1][py] < tp)
        que[++que[0]] = calc(px - 1, py);
      if (w[px + 1][py] >= ts && w[px + 1][py] < tp)
        que[++que[0]] = calc(px + 1, py);
      if (w[px][py - 1] >= ts && w[px][py - 1] < tp)
        que[++que[0]] = calc(px, py - 1);
      if (w[px][py + 1] >= ts && w[px][py + 1] < tp)
        que[++que[0]] = calc(px, py + 1);
      for (int i = 1; i <= que[0]; i++) cut(calc(px, py), que[i]);
      ts++;
      continue;
    }
    for (int i = 1; i <= que[0]; i++) link(calc(px, py), que[i]);
    tp++;
    continue;
  }
  for (int i = n * m; i > 0; i--) {
    int px = e[i].u, py = e[i].v;
    if (w[px - 1][py] > i) addit(w[px - 1][py], n * m, 1, -1);
    if (w[px + 1][py] > i) addit(w[px + 1][py], n * m, 1, -1);
    if (w[px][py - 1] > i) addit(w[px][py - 1], n * m, 1, -1);
    if (w[px][py + 1] > i) addit(w[px][py + 1], n * m, 1, -1);
    if (!pot[i]) pot[i] = n * m + 1;
    addit(i, n * m, 1, 1);
    search(i, pot[i] - 1, 1);
  }
  cout << ans << endl;
  return 0;
}
