#include <bits/stdc++.h>
using namespace std;
int read() {
  int X = 0;
  char ch = 0;
  while (ch < 48 || ch > 57) ch = getchar();
  while (ch >= 48 && ch <= 57) X = X * 10 + (ch ^ 48), ch = getchar();
  return X;
}
struct LCT {
  struct Node {
    int l, r, f;
    bool fl;
    inline void rev() {
      swap(l, r);
      fl ^= 1;
    }
  } a[200500];
  inline bool nrt(int u) { return a[a[u].f].l == u || a[a[u].f].r == u; }
  inline void ladd(int u) {
    if (a[u].fl) {
      a[a[u].l].rev();
      a[a[u].r].rev();
      a[u].fl = 0;
    }
  }
  void rot(int u) {
    int fa = a[u].f, gf = a[fa].f;
    ladd(fa);
    ladd(u);
    if (a[gf].l == fa) a[gf].l = u;
    if (a[gf].r == fa) a[gf].r = u;
    a[a[fa].f = u].f = gf;
    if (a[fa].l == u) {
      a[a[fa].l = a[u].r].f = fa;
      a[u].r = fa;
    } else {
      a[a[fa].r = a[u].l].f = fa;
      a[u].l = fa;
    }
  }
  void splay(int u) {
    ladd(u);
    while (nrt(u)) {
      int fa = a[u].f, gf = a[fa].f;
      if (nrt(fa) && (a[fa].l == u) == (a[gf].l == fa)) rot(fa);
      rot(u);
    }
  }
  void access(int u) {
    int sav = u;
    for (int v = 0; u; u = a[v = u].f) {
      splay(u);
      a[u].r = v;
    }
    splay(sav);
  }
  void makrt(int u) {
    access(u);
    a[u].rev();
  }
  int findrt(int u) {
    access(u);
    while (a[u].l) {
      ladd(u);
      u = a[u].l;
    }
    splay(u);
    return u;
  }
  void spilt(int u, int v) {
    makrt(u);
    access(v);
  }
  void link(int u, int v) {
    makrt(u);
    a[u].f = v;
  }
  void cut(int x, int y) {
    spilt(x, y);
    a[x].f = a[y].l = 0;
  }
  bool chk(int u, int v) { return findrt(u) == findrt(v); }
} T;
struct Node {
  int x, c, tg;
  inline void ladd(int t) {
    tg += t;
    x += t;
  }
} a[200500 << 2];
inline void up(int u) {
  int l = u << 1, r = u << 1 | 1;
  a[u].x = min(a[l].x, a[r].x);
  a[u].c =
      ((a[l].x == a[u].x) ? a[l].c : 0) + ((a[r].x == a[u].x) ? a[r].c : 0);
}
int n;
void build(int l = 1, int r = n, int u = 1) {
  if (l == r) {
    a[u].c = 1;
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, u << 1);
  build(mid + 1, r, u << 1 | 1);
  up(u);
}
inline void ladd(int u) {
  if (a[u].tg) {
    a[u << 1].ladd(a[u].tg);
    a[u << 1 | 1].ladd(a[u].tg);
    a[u].tg = 0;
  }
}
int wfl, wfr, wfc;
void add(int l = 1, int r = n, int u = 1) {
  if (wfl <= l && r <= wfr) {
    a[u].ladd(wfc);
    return;
  }
  int mid = (l + r) >> 1;
  ladd(u);
  if (wfl <= mid) add(l, mid, u << 1);
  if (mid < wfr) add(mid + 1, r, u << 1 | 1);
  up(u);
}
int qry(int l = 1, int r = n, int u = 1) {
  if (wfl <= l && r <= wfr) return a[u].x == 1 ? a[u].c : 0;
  int mid = (l + r) >> 1, ret = 0;
  ladd(u);
  if (wfl <= mid) ret = qry(l, mid, u << 1);
  if (mid < wfr) ret += qry(mid + 1, r, u << 1 | 1);
  return ret;
}
struct Data {
  int x, y;
} p[200500];
int m1, m2, x[200500];
void del(int u, int v, int tp, int tr) {
  if (tp <= x[v] && x[v] < tr) T.cut(u, v);
}
void delp(int x, int y, int tp, int tr) {
  if (1 < x) del((((x)-1) * m2 + (y)), (((x - 1) - 1) * m2 + (y)), tp, tr);
  if (1 < y) del((((x)-1) * m2 + (y)), (((x)-1) * m2 + (y - 1)), tp, tr);
  if (x < m1) del((((x)-1) * m2 + (y)), (((x + 1) - 1) * m2 + (y)), tp, tr);
  if (y < m2) del((((x)-1) * m2 + (y)), (((x)-1) * m2 + (y + 1)), tp, tr);
}
void adl(int u, int v, int &tp, int tr) {
  if (tr <= x[v]) return;
  for (; tp <= x[v] && T.chk(u, v); tp++) delp(p[tp].x, p[tp].y, tp, tr);
  if (x[v] < tp) return;
  T.link(u, v);
  wfl = 1;
  wfr = x[v];
  wfc = -1;
  add();
}
void addp(int x, int y, int &tp, int tr) {
  if (1 < x) adl((((x)-1) * m2 + (y)), (((x - 1) - 1) * m2 + (y)), tp, tr);
  if (1 < y) adl((((x)-1) * m2 + (y)), (((x)-1) * m2 + (y - 1)), tp, tr);
  if (x < m1) adl((((x)-1) * m2 + (y)), (((x + 1) - 1) * m2 + (y)), tp, tr);
  if (y < m2) adl((((x)-1) * m2 + (y)), (((x)-1) * m2 + (y + 1)), tp, tr);
}
int main() {
  m1 = read();
  m2 = read();
  n = m1 * m2;
  for (int i = 1; i <= m1; i++)
    for (int j = 1; j <= m2; j++)
      p[x[(((i)-1) * m2 + (j))] = read()] = (Data){i, j};
  long long ans = 0;
  build();
  for (int i = 1, tp = 1; i <= n; i++) {
    addp(p[i].x, p[i].y, tp, i);
    wfl = 1;
    wfr = i;
    wfc = 1;
    add();
    wfl = tp;
    wfr = i;
    ans += qry();
  }
  printf("%lld\n", ans);
  return 0;
}
