#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void rd(T &x) {
  char ch;
  x = 0;
  bool fl = false;
  while (!isdigit(ch = getchar())) (ch == '-') && (fl = true);
  for (x = (ch ^ '0'); isdigit(ch = getchar()); x = x * 10 + (ch ^ '0'))
    ;
  (fl == true) && (x = -x);
}
template <class T>
inline void output(T x) {
  if (x / 10) output(x / 10);
  putchar(x % 10 + '0');
}
template <class T>
inline void ot(T x) {
  if (x < 0) putchar('-'), x = -x;
  output(x);
  putchar(' ');
}
template <class T>
inline void prt(T a[], int st, int nd) {
  for (register int i = st; i <= nd; ++i) ot(a[i]);
  putchar('\n');
}
namespace Modulo {
const int mod = 998244353;
int ad(int x, int y) { return (x + y) >= mod ? x + y - mod : x + y; }
void inc(int &x, int y) { x = ad(x, y); }
int mul(int x, int y) { return (long long)x * y % mod; }
void inc2(int &x, int y) { x = mul(x, y); }
int qm(int x, int y = mod - 2) {
  int ret = 1;
  while (y) {
    if (y & 1) ret = mul(x, ret);
    x = mul(x, x);
    y >>= 1;
  }
  return ret;
}
}  // namespace Modulo
namespace Miracle {
const int N = 2e5 + 5;
const int inf = 0x3f3f3f3f;
const int mv[4][2] = {{+1, 0}, {-1, 0}, {0, -1}, {0, +1}};
int a[2002][2002];
int n;
int ha, li;
pair<int, int> pos[N];
struct node {
  int ch[2];
  int fa;
  int rev;
} t[N];
int L, R;
bool nrt(int x) { return (t[t[x].fa].ch[0] == x || t[t[x].fa].ch[1] == x); }
void rotate(int x) {
  int y = t[x].fa, d = t[y].ch[1] == x;
  t[t[y].ch[d] = t[x].ch[!d]].fa = y;
  if (nrt(y))
    t[t[x].fa = t[y].fa].ch[t[t[y].fa].ch[1] == y] = x;
  else
    t[x].fa = t[y].fa;
  t[t[x].ch[!d] = y].fa = x;
}
int sta[N];
void rev(int x) {
  t[x].rev ^= 1;
  swap(t[x].ch[0], t[x].ch[1]);
}
void pd(int x) {
  if (t[x].rev) {
    rev(t[x].ch[0]);
    rev(t[x].ch[1]);
    t[x].rev = 0;
  }
}
void splay(int x) {
  int y = x, z = 0;
  sta[++z] = y;
  while (nrt(y)) y = t[y].fa, sta[++z] = y;
  while (z) pd(sta[z--]);
  while (nrt(x)) {
    y = t[x].fa, z = t[y].fa;
    if (nrt(y)) {
      rotate((t[y].ch[0] == x) == (t[z].ch[0] == y) ? y : x);
    }
    rotate(x);
  }
}
void access(int x) {
  for (register int y = 0; x; y = x, x = t[x].fa) {
    splay(x);
    t[x].ch[1] = y;
  }
}
void makert(int x) {
  access(x);
  splay(x);
  rev(x);
}
int findrt(int x) {
  access(x);
  splay(x);
  while (t[x].ch[0]) x = t[x].ch[0];
  splay(x);
  return x;
}
bool link(int x, int y) {
  makert(x);
  if (findrt(y) != x) {
    t[x].fa = y;
    return true;
  } else
    return false;
}
void cut(int x, int y) {
  makert(x);
  access(y);
  splay(y);
  if (t[y].ch[0] == x && !t[x].ch[0] && !t[x].ch[1]) {
    t[x].fa = 0;
    t[y].ch[0] = 0;
  }
}
void dele(int x) {
  int nx = pos[x].first, ny = pos[x].second;
  for (register int i = 0; i < 4; ++i) {
    int tx = nx + mv[i][0], ty = ny + mv[i][1];
    if (a[tx][ty]) {
      int p = a[tx][ty];
      if (p >= L && p <= R) {
        cut(x, p);
      }
    }
  }
}
int got[10];
bool che(int x) {
  bool fl = true;
  int nx = pos[x].first, ny = pos[x].second;
  int ct = 0;
  for (register int i = 0; i < 4; ++i) {
    int tx = nx + mv[i][0], ty = ny + mv[i][1];
    if (a[tx][ty]) {
      int p = a[tx][ty];
      if (p >= L && p <= R) {
        bool lp = link(x, p);
        if (lp == false) {
          fl = false;
          break;
        }
        got[++ct] = p;
      }
    }
  }
  if (!fl) {
    for (register int i = 1; i <= ct; ++i) cut(x, got[i]);
  }
  return fl;
}
struct po {
  int mi, cnt;
  po() { mi = inf, cnt = 1; }
  po friend operator+(po a, po b) {
    po c;
    c.mi = min(a.mi, b.mi);
    c.cnt = 0;
    if (a.mi == c.mi) c.cnt += a.cnt;
    if (b.mi == c.mi) c.cnt += b.cnt;
    return c;
  }
};
namespace seg {
struct tr {
  po v;
  int add;
} t[4 * N];
void pushup(int x) { t[x].v = t[(x << 1)].v + t[(x << 1 | 1)].v; }
void tag(int x, int c) {
  t[x].add += c;
  t[x].v.mi += c;
}
void pushdown(int x) {
  if (t[x].add) {
    tag((x << 1), t[x].add);
    tag((x << 1 | 1), t[x].add);
    t[x].add = 0;
  }
}
void build(int x, int l, int r) {
  if (l == r) {
    t[x].add = 0;
    t[x].v.mi = 0;
    t[x].v.cnt = 1;
    return;
  }
  build((x << 1), l, ((l + r) >> 1));
  build((x << 1 | 1), ((l + r) >> 1) + 1, r);
  pushup(x);
}
void upda(int x, int l, int r, int L, int R, int c) {
  if (L <= l && r <= R) {
    tag(x, c);
    return;
  }
  pushdown(x);
  if (L <= ((l + r) >> 1)) upda((x << 1), l, ((l + r) >> 1), L, R, c);
  if (((l + r) >> 1) < R) upda((x << 1 | 1), ((l + r) >> 1) + 1, r, L, R, c);
  pushup(x);
}
po query(int x, int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    return t[x].v;
  }
  po ret;
  if (L <= ((l + r) >> 1)) ret = ret + query((x << 1), l, ((l + r) >> 1), L, R);
  if (((l + r) >> 1) < R)
    ret = ret + query((x << 1 | 1), ((l + r) >> 1) + 1, r, L, R);
  return ret;
}
}  // namespace seg
int main() {
  rd(ha);
  rd(li);
  n = ha * li;
  for (register int i = 1; i <= ha; ++i) {
    for (register int j = 1; j <= li; ++j) {
      rd(a[i][j]);
      pos[a[i][j]] = make_pair(i, j);
    }
  }
  seg::build(1, 1, n);
  L = 1;
  long long ans = 0;
  for (R = 1; R <= n; ++R) {
    while (!che(R)) {
      dele(L);
      ++L;
    }
    seg::upda(1, 1, n, L, R, 1);
    int x = R;
    int nx = pos[x].first, ny = pos[x].second;
    for (register int i = 0; i < 4; ++i) {
      int tx = nx + mv[i][0], ty = ny + mv[i][1];
      if (a[tx][ty]) {
        int p = a[tx][ty];
        if (p >= L && p <= R) {
          seg::upda(1, 1, n, L, p, -1);
        }
      }
    }
    po now = seg::query(1, 1, n, L, R);
    if (now.mi == 1) {
      ans += now.cnt;
    }
  }
  ot(ans);
  return 0;
}
}  // namespace Miracle
signed main() {
  Miracle::main();
  return 0;
}
