#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
  int flag = 1;
  char ch;
  while (!isdigit(ch = getchar()))
    if (ch == '-') flag = -flag;
  for (x = 0; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  x *= flag;
}
const int MAXN = 1005;
const int MAXP = 1000005;
const int INF = 1e9;
namespace LCT {
int ch[MAXP][2], fa[MAXP];
bool rev[MAXP];
inline bool isr(int x) { return ch[fa[x]][0] != x && ch[fa[x]][1] != x; }
inline bool get(int x) { return ch[fa[x]][1] == x; }
inline void mt(int x) {
  if (rev[x])
    rev[x] ^= 1, rev[ch[x][0]] ^= 1, rev[ch[x][1]] ^= 1,
        swap(ch[x][0], ch[x][1]);
}
void mtpath(int x) {
  if (!isr(x)) mtpath(fa[x]);
  mt(x);
}
inline void rot(int x) {
  int y = fa[x], z = fa[y];
  bool l = get(x), r = l ^ 1;
  if (!isr(y)) ch[z][get(y)] = x;
  fa[ch[x][r]] = y;
  fa[y] = x;
  fa[x] = z;
  ch[y][l] = ch[x][r];
  ch[x][r] = y;
}
inline void splay(int x) {
  mtpath(x);
  for (; !isr(x); rot(x))
    if (!isr(fa[x])) rot(get(fa[x]) == get(x) ? fa[x] : x);
}
inline void access(int x) {
  int y = 0;
  for (; x; x = fa[y = x]) splay(x), ch[x][1] = y;
}
inline void bert(int x) { access(x), splay(x), rev[x] ^= 1; }
inline int sert(int x) {
  access(x), splay(x);
  for (; ch[x][0]; x = ch[x][0])
    ;
  return x;
}
inline void link(int x, int y) {
  bert(x);
  if (sert(y) != x) fa[x] = y;
}
inline void cut(int x, int y) {
  bert(x);
  sert(y);
  fa[x] = ch[y][0] = 0;
}
inline bool connect(int x, int y) {
  bert(x);
  return sert(y) == x;
}
}  // namespace LCT
using namespace LCT;
int n, m, a[MAXN][MAXN], tot;
pair<int, int> pos[MAXP], val[MAXP << 2];
int lz[MAXP << 2];
inline pair<int, int> merge(pair<int, int> A, pair<int, int> B) {
  if (A.first < B.first)
    return A;
  else if (A.first > B.first)
    return B;
  return pair<int, int>(A.first, A.second + B.second);
}
inline void upd(int i) { val[i] = merge(val[i << 1], val[i << 1 | 1]); }
inline void pd(int i) {
  if (lz[i]) {
    val[i << 1].first += lz[i], lz[i << 1] += lz[i];
    val[i << 1 | 1].first += lz[i], lz[i << 1 | 1] += lz[i];
    lz[i] = 0;
  }
}
void build(int i, int l, int r) {
  if (l == r) {
    val[i] = pair<int, int>(0, 1);
    return;
  }
  int mid = (l + r) >> 1;
  build(i << 1, l, mid);
  build(i << 1 | 1, mid + 1, r);
  upd(i);
}
void modify(int i, int l, int r, int x, int y, int v) {
  if (x <= l && r <= y) {
    val[i].first += v, lz[i] += v;
    return;
  }
  pd(i);
  int mid = (l + r) >> 1;
  if (x <= mid) modify(i << 1, l, mid, x, y, v);
  if (y > mid) modify(i << 1 | 1, mid + 1, r, x, y, v);
  upd(i);
}
pair<int, int> query(int i, int l, int r, int x, int y) {
  if (x <= l && r <= y) return val[i];
  pd(i);
  int mid = (l + r) >> 1;
  pair<int, int> re = pair<int, int>(INF, 0);
  if (x <= mid) re = merge(re, query(i << 1, l, mid, x, y));
  if (y > mid) re = merge(re, query(i << 1 | 1, mid + 1, r, x, y));
  return re;
}
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};
inline bool chkout(int x, int y) { return x < 1 || y < 1 || x > n || y > m; }
inline bool check(int l, int r) {
  for (int i = 0; i < 3; ++i) {
    int x = pos[r].first + dx[i];
    int y = pos[r].second + dy[i];
    if (chkout(x, y) || a[x][y] < l || a[x][y] > r) continue;
    for (int j = i + 1; j < 4; ++j) {
      int u = pos[r].first + dx[j];
      int v = pos[r].second + dy[j];
      if (chkout(u, v) || a[u][v] < l || a[u][v] > r) continue;
      if (connect(a[x][y], a[u][v])) return 0;
    }
  }
  return 1;
}
inline void del(int l) {
  for (int i = 0; i < 4; ++i) {
    int x = pos[l].first + dx[i];
    int y = pos[l].second + dy[i];
    if (chkout(x, y) || !connect(l, a[x][y])) continue;
    cut(l, a[x][y]);
  }
}
inline void solve(int l, int r) {
  for (int i = 0; i < 4; ++i) {
    int x = pos[r].first + dx[i];
    int y = pos[r].second + dy[i];
    if (chkout(x, y) || a[x][y] < l || a[x][y] > r) continue;
    link(a[x][y], r);
    modify(1, 1, tot, 1, a[x][y], -1);
  }
  modify(1, 1, tot, l, r, 1);
}
int main() {
  scanf("%d%d", &n, &m);
  tot = n * m;
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      scanf("%d", &a[i][j]), pos[a[i][j]] = pair<int, int>(i, j);
  build(1, 1, tot);
  long long ans = 0;
  for (int i = 1, j = 1; i <= tot; ++i) {
    while (!check(j, i)) del(j++);
    solve(j, i);
    ans += query(1, 1, tot, j, i).second;
  }
  printf("%I64d\n", ans);
}
