#include <bits/stdc++.h>
using namespace std;
const int N = 2 * 1e5 + 10;
const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, -1, 1};
int n;
int m;
struct mar {
  int f[N * 2];
  inline int* operator[](const int& x) { return f + x * m; }
} val;
bool book[N];
struct data {
  int x;
  int y;
} nod[N];
int ctt;
int ptr;
int totr;
struct tnod {
  int val;
  int cnt;
  friend tnod operator+(tnod a, tnod b) {
    if (a.val < b.val) return a;
    if (a.val > b.val) return b;
    return (tnod){a.val, a.cnt + b.cnt};
  }
  void operator+=(const int& x) { val += x; }
};
struct linkcuttree {
  int s[N][2];
  int fa[N];
  int mi[N];
  int rv[N];
  int st[N];
  int tp;
  linkcuttree() { mi[0] = 0x3f3f3f3f; }
  inline int gc(int x) { return s[fa[x]][1] == x; }
  inline bool isr(int x) { return (s[fa[x]][1] != x && s[fa[x]][0] != x); }
  inline void ud(int x) { mi[x] = min(min(mi[s[x][0]], mi[s[x][1]]), x); }
  inline void pd(int p) {
    if (rv[p])
      rv[s[p][0]] ^= 1, rv[s[p][1]] ^= 1, swap(s[p][0], s[p][1]), rv[p] = 0;
  }
  inline void pdall(int p) {
    for (int x = p; (st[++tp] = x, !isr(x)); x = fa[x])
      ;
    while (tp) pd(st[tp--]);
  }
  inline void rt(int x) {
    int d = fa[x];
    int t = gc(x);
    s[d][t] = s[x][t ^ 1];
    fa[s[x][t ^ 1]] = d;
    if (!isr(d)) s[fa[d]][gc(d)] = x;
    fa[x] = fa[d];
    s[x][t ^ 1] = d;
    fa[d] = x;
    ud(d);
    ud(x);
  }
  inline void rtup(int x) {
    rt((gc(x) ^ gc(fa[x])) ? x : fa[x]);
    rt(x);
  }
  inline void splay(int x) {
    pdall(x);
    for (; !isr(x) && !isr(fa[x]); rtup(x))
      ;
    if (!isr(x)) rt(x);
  }
  inline void acc(int p) {
    for (splay(p), s[p][1] = 0, ud(p); fa[p];
         splay(fa[p]), s[fa[p]][1] = p, ud(fa[p]), splay(p))
      ;
  }
  inline void mkr(int p) {
    acc(p);
    rv[p] ^= 1;
  }
  inline void lk(int u, int v) {
    mkr(u);
    acc(v);
    fa[u] = v;
  }
  inline void cu(int u, int v) {
    mkr(u);
    acc(v);
    if (s[v][0] == u && s[u][1] == 0) s[v][0] = 0, fa[u] = 0, ud(v);
  }
  inline int cmi(int u, int v) {
    mkr(u);
    acc(v);
    if (fa[u] == 0)
      return 0x3f3f3f3f;
    else
      return mi[v];
  }
} lct;
struct linetree {
  tnod v[N << 2];
  int add[N << 2];
  inline void pd(int p, int p1, int p2) {
    if (add[p])
      v[p1] += add[p], v[p2] += add[p], add[p1] += add[p], add[p2] += add[p],
          add[p] = 0;
  }
  inline void build(int p, int l, int r) {
    v[p] = (tnod){0, r - l};
    if (r - l == 1) {
      return;
    }
    int mid = (l + r) >> 1;
    build(p << 1, l, mid);
    build(p << 1 | 1, mid, r);
  }
  inline void stadd(int p, int l, int r, int dl, int dr, int pl) {
    if (dl == l && dr == r) {
      v[p] += pl;
      add[p] += pl;
      return;
    }
    int mid = (l + r) >> 1;
    pd(p, p << 1, p << 1 | 1);
    if (dl < mid) stadd(p << 1, l, mid, dl, min(dr, mid), pl);
    if (mid < dr) stadd(p << 1 | 1, mid, r, max(dl, mid), dr, pl);
    v[p] = v[p << 1] + v[p << 1 | 1];
  }
  inline tnod sum(int p, int l, int r, int dl, int dr) {
    if (dl == l && dr == r) return v[p];
    int mid = (l + r) >> 1;
    pd(p, p << 1, p << 1 | 1);
    if (dl < mid && mid < dr)
      return sum(p << 1, l, mid, dl, mid) + sum(p << 1 | 1, mid, r, mid, dr);
    if (dl < mid)
      return sum(p << 1, l, mid, dl, dr);
    else
      return sum(p << 1 | 1, mid, r, dl, dr);
  }
} lt;
inline void delnod(int sx, int sy) {
  int np = val[sx][sy];
  for (int k = 0, tx, ty; k < 4; k++) {
    tx = sx + dx[k];
    ty = sy + dy[k];
    if (tx < 1 || tx > n || ty < 1 || ty > m || val[tx][ty] < ptr ||
        val[tx][ty] > totr)
      continue;
    lct.cu(np, val[tx][ty]);
  }
  ptr++;
}
inline void insed(int p1, int p2) {
  lt.stadd(1, 0, ctt, 0, p2, -1);
  int tmp = lct.cmi(p1, p2);
  if (tmp == 0x3f3f3f3f) {
    lct.lk(p1, p2);
    return;
  }
  for (int k = ptr; k <= tmp; k++) delnod(nod[k].x, nod[k].y);
  lct.lk(p1, p2);
}
int main() {
  scanf("%d%d", &n, &m);
  ctt = n * m;
  lt.build(1, 0, ctt);
  for (int i = 1; i <= n; i++)
    for (int j = 1, t; j <= m; j++)
      scanf("%d", &t), val[i][j] = t, nod[t] = (data){i, j};
  long long ans = 0;
  ptr = 1;
  totr = 1;
  for (int i = 1; i <= ctt; i++) {
    totr = i;
    int sx = nod[i].x;
    int sy = nod[i].y;
    lt.stadd(1, 0, ctt, 0, i, 1);
    for (int k = 0, tx, ty; k < 4; k++) {
      tx = sx + dx[k], ty = sy + dy[k];
      if (tx < 1 || tx > n || ty < 1 || ty > m || val[tx][ty] > i ||
          val[tx][ty] < ptr)
        continue;
      insed(i, val[tx][ty]);
    }
    tnod ret = lt.sum(1, 0, ctt, ptr - 1, i);
    if (ret.val == 1) ans += ret.cnt;
  }
  printf("%I64d", ans);
  return 0;
}
