#include <bits/stdc++.h>
using namespace std;
inline int gi() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = (x << 3) + (x << 1) + ch - 48;
    ch = getchar();
  }
  return x * f;
}
template <typename T>
inline bool Max(T &a, T b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T>
inline bool Min(T &a, T b) {
  return a > b ? a = b, 1 : 0;
}
const int N = 2e5 + 7;
int n, m;
int a[1007][1007], c[N], r[N];
int dr[] = {1, 0, -1, 0}, dc[] = {0, -1, 0, 1};
namespace lct {
int t[N][2], fa[N], rev[N], L[N], R[N];
bool isrt(int o) { return t[fa[o]][0] != o && t[fa[o]][1] != o; }
int side(int o) { return t[fa[o]][1] == o; }
void Reverse(int o) {
  rev[o] ^= 1;
  swap(L[t[o][0]], L[t[o][1]]);
  swap(R[t[o][0]], R[t[o][1]]);
  swap(t[o][0], t[o][1]);
}
void pushup(int o) {
  L[o] = t[o][0] ? L[t[o][0]] : o;
  R[o] = t[o][1] ? R[t[o][1]] : o;
}
void pushdown(int o) {
  if (!rev[o]) return;
  Reverse(t[o][0]);
  Reverse(t[o][1]);
  rev[o] = 0;
}
void rotate(int o) {
  int f = fa[o], y = fa[f], x = side(o), s = t[o][x ^ 1];
  if (!isrt(f)) t[y][side(f)] = o;
  fa[o] = y;
  t[f][x] = s, fa[s] = f;
  t[o][x ^ 1] = f, fa[f] = o;
  pushup(f), pushup(o);
}
int stk[N];
void push(int o) {
  int tp = 0;
  stk[++tp] = o;
  for (; !isrt(o); o = fa[o]) stk[++tp] = fa[o];
  for (; tp; --tp) pushdown(stk[tp]);
}
void splay(int o) {
  push(o);
  for (; !isrt(o); rotate(o))
    if (!isrt(fa[o])) rotate(side(o) == side(fa[o]) ? fa[o] : o);
}
void access(int o) {
  for (int y = 0; o; y = o, o = fa[o]) {
    splay(o);
    t[o][1] = y;
    pushup(o);
  }
}
void maker(int o) {
  access(o);
  splay(o);
  Reverse(o);
}
void link(int x, int y) {
  maker(x);
  fa[x] = y;
}
void cut(int x, int y) {
  maker(x);
  access(y);
  splay(y);
  fa[x] = t[y][0] = 0;
  pushup(y);
}
int findr(int o) {
  access(o);
  splay(o);
  return rev[o] ? R[o] : L[o];
}
}  // namespace lct
int mi[N << 2], adv[N << 2], sum[N << 2];
void st1(int o, int v) {
  adv[o] += v;
  mi[o] += v;
}
void pushdown(int o) {
  if (!adv[o]) return;
  st1(o << 1, adv[o]);
  st1(o << 1 | 1, adv[o]);
  adv[o] = 0;
}
void pushup(int o) {
  mi[o] = min(mi[o << 1], mi[o << 1 | 1]);
  sum[o] = 0;
  if (mi[o] == mi[o << 1]) sum[o] += sum[o << 1];
  if (mi[o] == mi[o << 1 | 1]) sum[o] += sum[o << 1 | 1];
}
void build(int l, int r, int o) {
  if (l == r) {
    sum[o] = 1;
    return;
  }
  int mid = l + r >> 1;
  build(l, mid, o << 1);
  build(mid + 1, r, o << 1 | 1);
  pushup(o);
}
void modify(int L, int R, int l, int r, int o, int v) {
  if (L <= l && r <= R) {
    st1(o, v);
    return;
  }
  pushdown(o);
  int mid = l + r >> 1;
  if (L <= mid) modify(L, R, l, mid, o << 1, v);
  if (R > mid) modify(L, R, mid + 1, r, o << 1 | 1, v);
  pushup(o);
}
int query(int L, int R, int l, int r, int o) {
  if (L <= l && r <= R) return mi[o] == 1 ? sum[o] : 0;
  pushdown(o);
  int mid = l + r >> 1;
  if (R <= mid) return query(L, R, l, mid, o << 1);
  if (L > mid) return query(L, R, mid + 1, r, o << 1 | 1);
  return query(L, R, l, mid, o << 1) + query(L, R, mid + 1, r, o << 1 | 1);
}
int qmi(int L, int R, int l, int r, int o) {
  if (L <= l && r <= R) return mi[o];
  pushdown(o);
  int mid = l + r >> 1;
  if (R <= mid) return qmi(L, R, l, mid, o << 1);
  if (L > mid) return qmi(L, R, mid + 1, r, o << 1 | 1);
  return min(qmi(L, R, l, mid, o << 1), qmi(L, R, mid + 1, r, o << 1 | 1));
}
bool inside(int r, int c, int L, int R) {
  return r && c && r <= n && c <= m && L <= a[r][c] && a[r][c] <= R;
}
long long ans;
int main() {
  using namespace lct;
  n = gi(), m = gi();
  int maxn = n * m;
  build(1, maxn, 1);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j) a[i][j] = gi(), r[a[i][j]] = i, c[a[i][j]] = j;
  for (int i = 1, now = 1; i <= n * m; ++i) {
    int r = ::r[i], c = ::c[i];
    int tmp = 0;
    while (1) {
      bool fg = 1;
      int tt[4];
      for (int d = 0; d <= 3; ++d) {
        int tr = r + dr[d], tc = c + dc[d];
        if (inside(tr, tc, now, i))
          tt[d] = findr(a[tr][tc]);
        else
          tt[d] = -1;
      }
      for (int a = 0; a <= 3; ++a)
        for (int b = 0; b <= a - 1; ++b)
          if (tt[a] != -1 && tt[b] != -1 && tt[a] == tt[b]) fg = 0;
      if (fg) {
        for (int d = 0; d <= 3; ++d) {
          int tr = r + dr[d], tc = c + dc[d];
          if (inside(tr, tc, now, i)) link(i, a[tr][tc]);
        }
        break;
      } else {
        for (int d = 0; d <= 3; ++d) {
          int tr = ::r[now] + dr[d], tc = ::c[now] + dc[d];
          if (inside(tr, tc, now, i)) cut(now, a[tr][tc]);
        }
        ++now;
      }
    }
    modify(1, i, 1, maxn, 1, 1);
    for (int d = 0; d <= 3; ++d) {
      int tr = r + dr[d], tc = c + dc[d];
      if (inside(tr, tc, now, i)) modify(1, a[tr][tc], 1, maxn, 1, -1);
    }
    ans += query(now, i, 1, maxn, 1);
  }
  printf("%lld\n", ans);
  return 0;
}
