#include <bits/stdc++.h>   using namespace std;   const int N = 200010;   const int px[] = {0, 0, 1, -1}, py[] = {1, -1, 0, 0};   int n, m, a[1010][1010], tx[N], ty[N], f[N], ch[N][2], rev[N], tr[N * 4],       cnt[N * 4], tag[N * 4];   long long ans;   bool isroot(int x) {     return !x || !f[x] || (ch[f[x]][0] != x && ch[f[x]][1] != x);   }   int which(int x) { return ch[f[x]][1] == x; }   void rotate(int x) {     int fx = f[x], ffx = f[fx], d = which(x);     if (!isroot(fx)) ch[ffx][which(fx)] = x;     f[x] = f[fx];     ch[fx][d] = ch[x][d ^ 1];     f[ch[x][d ^ 1]] = fx;     ch[x][d ^ 1] = fx;     f[fx] = x;     return;   }   void rever(int x) {     rev[x] ^= 1;     swap(ch[x][0], ch[x][1]);     return;   }   void pushdown(int x) {     if (rev[x]) {       if (ch[x][0]) rever(ch[x][0]);       if (ch[x][1]) rever(ch[x][1]);       rev[x] = 0;     }     return;   }   void push(int x) {     if (!isroot(x)) push(f[x]);     pushdown(x);     return;   }   void splay(int x) {     push(x);     while (!isroot(x)) {       int fx = f[x];       if (!isroot(fx)) {         if (which(x) == which(fx))           rotate(fx);         else           rotate(x);       }       rotate(x);     }     return;   }   void access(int x) {     for (int y = 0; x; y = x, x = f[x]) {       splay(x);       ch[x][1] = y;     }     return;   }   void makeroot(int x) {     access(x);     splay(x);     rever(x);     return;   }   void link(int x, int y) {     makeroot(x);     f[x] = y;     return;   }   int getroot(int x) {     access(x);     splay(x);     while (ch[x][0]) x = ch[x][0];     return x;   }   void cut(int x, int y) {     makeroot(x);     access(y);     splay(y);     if (!ch[x][1] && ch[y][0] == x) f[x] = ch[y][0] = 0;     return;   }   bool check(int x, int y) {     makeroot(x);     access(y);     splay(y);     while (f[x]) x = f[x];     return x == y;   }   void sgtpushdown(int o) {     if (tag[o]) {       tr[o << 1] += tag[o];       tr[o << 1 | 1] += tag[o];       tag[o << 1] += tag[o];       tag[o << 1 | 1] += tag[o];       tag[o] = 0;     }     return;   }   void pushup(int o) {     if (tr[o << 1] == tr[o << 1 | 1]) {       tr[o] = tr[o << 1];       cnt[o] = cnt[o << 1] + cnt[o << 1 | 1];     } else if (tr[o << 1] < tr[o << 1 | 1]) {       tr[o] = tr[o << 1];       cnt[o] = cnt[o << 1];     } else {       tr[o] = tr[o << 1 | 1];       cnt[o] = cnt[o << 1 | 1];     }     return;   }   void build(int o, int l, int r) {     tr[o] = 0;     cnt[o] = r - l + 1;     if (l == r) return;     int mid = (l + r) >> 1;     build(o << 1, l, mid);     build(o << 1 | 1, mid + 1, r);     return;   }   void update(int o, int l, int r, int L, int R, int v) {     if (L <= l && r <= R) {       tag[o] += v;       tr[o] += v;       return;     }     sgtpushdown(o);     int mid = (l + r) >> 1;     if (L <= mid) update(o << 1, l, mid, L, R, v);     if (R > mid) update(o << 1 | 1, mid + 1, r, L, R, v);     pushup(o);     return;   }   int query(int o, int l, int r, int L, int R) {     if (tr[o] > 1) return 0;     if (L <= l && r <= R) return tr[o] * cnt[o];     sgtpushdown(o);     int mid = (l + r) >> 1, ret = 0;     if (L <= mid) ret += query(o << 1, l, mid, L, R);     if (R > mid) ret += query(o << 1 | 1, mid + 1, r, L, R);     return ret;   }   int main() {     scanf( %d%d , &n, &m);     for (int i = 1; i <= n; i++)       for (int j = 1; j <= m; j++) {         scanf( %d , a[i] + j);         tx[a[i][j]] = i;         ty[a[i][j]] = j;       }     int M = n * m;     build(1, 1, M);     for (int l = n * m, r = l; l >= 1; l--) {       int x = tx[l], y = ty[l];       for (int i = 0; i <= 3; i++) {         int nx = x + px[i], ny = y + py[i];         if (nx <= n && nx >= 1 && ny <= m && ny >= 1) {           while (a[nx][ny] >= l && a[nx][ny] <= r && check(a[x][y], a[nx][ny])) {             for (int j = 0; j <= 3; j++) {               int mx = tx[r] + px[j], my = ty[r] + py[j];               if (mx <= n && mx >= 1 && my <= m && my >= 1)                 cut(a[tx[r]][ty[r]], a[mx][my]);             }             r--;           }           if (a[nx][ny] >= l && a[nx][ny] <= r) {             link(a[x][y], a[nx][ny]);             update(1, 1, M, a[nx][ny], r, -1);           }         }       }       update(1, 1, M, l, r, 1);       ans += query(1, 1, M, l, r);     }     printf( %lld n , ans);     return 0;   }