#include <bits/stdc++.h>   using namespace std;   inline void open(const char *s) {}   inline int rd() {     static int x, f;     x = 0;     f = 1;     char ch = getchar();     for (; ch <  0  || ch >  9 ; ch = getchar())       if (ch ==  - ) f = -1;     for (; ch >=  0  && ch <=  9 ; ch = getchar()) x = x * 10 + ch -  0 ;     return f > 0 ? x : -x;   }   const int N = 1000010;   int R, C, n, rt = 0, Lr;   vector<int> a[N];   pair<int, int> b[N];   namespace LCT {   struct tree {     int ch[2], fa, rev;     tree() { ch[0] = ch[1] = fa = rev = 0; }   } tr[N];   int cnt = 0;   inline bool isrt(int x) {     return tr[tr[x].fa].ch[0] != x && tr[tr[x].fa].ch[1] != x;   }   inline void pushdown(int x) {     if (!tr[x].rev) return;     swap(tr[x].ch[0], tr[x].ch[1]);     if (tr[x].ch[0]) tr[tr[x].ch[0]].rev ^= 1;     if (tr[x].ch[1]) tr[tr[x].ch[1]].rev ^= 1;     tr[x].rev = 0;   }   inline void clr(int x) {     static int st[N], tt;     for (st[tt = 1] = x; !isrt(x); x = tr[x].fa) st[++tt] = tr[x].fa;     while (tt) pushdown(st[tt--]);   }   inline void rotate(int x) {     static int y, z, t1, t2;     y = tr[x].fa;     z = tr[y].fa;     t1 = tr[y].ch[1] == x;     t2 = t1 ^ 1;     if (!isrt(y)) tr[z].ch[tr[z].ch[1] == y] = x;     tr[x].fa = z;     tr[y].fa = x;     if (tr[x].ch[t2]) tr[tr[x].ch[t2]].fa = y;     tr[y].ch[t1] = tr[x].ch[t2];     tr[x].ch[t2] = y;   }   inline void splay(int x) {     for (clr(x); !isrt(x); rotate(x)) {       int y = tr[x].fa, z = tr[y].fa;       if (isrt(y)) continue;       if ((tr[y].ch[0] == x) ^ (tr[z].ch[0] == y))         rotate(x);       else         rotate(y);     }   }   inline void access(int x) {     for (int s = 0; x; s = x, x = tr[x].fa) {       splay(x);       tr[x].ch[1] = s;     }   }   inline void makert(int x) {     access(x);     splay(x);     tr[x].rev ^= 1;   }   inline int findrt(int x) {     access(x);     splay(x);     pushdown(x);     while (tr[x].ch[0]) x = tr[x].ch[0], pushdown(x);     return x;   }   inline void link(int x, int y) {     makert(x);     access(y);     splay(y);     tr[x].fa = y;   }   inline void cut(int x, int y) {     makert(y);     access(x);     splay(x);     tr[tr[x].ch[0]].fa = 0;     tr[x].ch[0] = 0;   }   }  // namespace LCT   namespace Seg {   struct tree {     int ls, rs, mx, cmx, tag;     tree() { ls = rs = mx = cmx = tag = 0; }   } tr[N << 1];   int cnt = 0;   inline void pushup(int o) {     tr[o].mx = max(tr[tr[o].ls].mx, tr[tr[o].rs].mx);     tr[o].cmx = 0;     if (tr[o].mx == tr[tr[o].ls].mx) tr[o].cmx += tr[tr[o].ls].cmx;     if (tr[o].mx == tr[tr[o].rs].mx) tr[o].cmx += tr[tr[o].rs].cmx;   }   inline void pushdown(int o) {     if (!tr[o].tag) return;     static int ls, rs;     ls = tr[o].ls, rs = tr[o].rs;     tr[ls].mx += tr[o].tag;     tr[ls].tag += tr[o].tag;     tr[rs].mx += tr[o].tag;     tr[rs].tag += tr[o].tag;     tr[o].tag = 0;   }   void build(int &o, int l, int r) {     o = ++cnt;     if (l == r) return tr[o].mx = l, tr[o].cmx = 1, void();     int mid = (l + r) >> 1;     build(tr[o].ls, l, mid);     build(tr[o].rs, mid + 1, r);     pushup(o);   }   void modify(int o, int l, int r, int L, int R, int d) {     if (l == L && r == R) return tr[o].mx += d, tr[o].tag += d, void();     pushdown(o);     int mid = (l + r) >> 1;     if (L <= mid) modify(tr[o].ls, l, mid, L, min(mid, R), d);     if (R > mid) modify(tr[o].rs, mid + 1, r, max(mid + 1, L), R, d);     pushup(o);   }   pair<int, int> query(int o, int l, int r, int L, int R) {     if (l == L && r == R) return pair<int, int>(tr[o].mx, tr[o].cmx);     pushdown(o);     int mid = (l + r) >> 1;     pair<int, int> res = pair<int, int>(0, 0), tmp;     if (L <= mid) res = query(tr[o].ls, l, mid, L, min(mid, R));     if (R > mid) {       tmp = query(tr[o].rs, mid + 1, r, max(mid + 1, L), R);       if (res.first == tmp.first)         res.second += tmp.second;       else         res = max(res, tmp);     }     return res;   }   }  // namespace Seg   inline bool check(int p) {     static int d[5], tt, x, y;     tt = 0;     x = b[p].first, y = b[p].second;     if (x > 1 && a[x - 1][y] >= Lr && a[x - 1][y] < p)       d[++tt] = LCT::findrt(a[x - 1][y]);     if (y > 1 && a[x][y - 1] >= Lr && a[x][y - 1] < p)       d[++tt] = LCT::findrt(a[x][y - 1]);     if (x < R && a[x + 1][y] >= Lr && a[x + 1][y] < p)       d[++tt] = LCT::findrt(a[x + 1][y]);     if (y < C && a[x][y + 1] >= Lr && a[x][y + 1] < p)       d[++tt] = LCT::findrt(a[x][y + 1]);     sort(d + 1, d + tt + 1);     for (int i = 1; i <= tt - 1; i++)       if (d[i] == d[i + 1]) return 0;     return 1;   }   inline void del(int p) {     static int x, y;     x = b[p].first, y = b[p].second;     if (x > 1 && a[x - 1][y] >= p) LCT::cut(a[x - 1][y], p);     if (y > 1 && a[x][y - 1] >= p) LCT::cut(a[x][y - 1], p);     if (x < R && a[x + 1][y] >= p) LCT::cut(a[x + 1][y], p);     if (y < C && a[x][y + 1] >= p) LCT::cut(a[x][y + 1], p);   }   inline void gao(int p) {     static int x, y;     for (; !check(p); ++Lr) del(Lr);     x = b[p].first, y = b[p].second;     if (x > 1 && a[x - 1][y] >= Lr && a[x - 1][y] < p) {       LCT::link(a[x - 1][y], p);       Seg::modify(rt, 1, n, 1, a[x - 1][y], 1);     }     if (y > 1 && a[x][y - 1] >= Lr && a[x][y - 1] < p) {       LCT::link(a[x][y - 1], p);       Seg::modify(rt, 1, n, 1, a[x][y - 1], 1);     }     if (x < R && a[x + 1][y] >= Lr && a[x + 1][y] < p) {       LCT::link(a[x + 1][y], p);       Seg::modify(rt, 1, n, 1, a[x + 1][y], 1);     }     if (y < C && a[x][y + 1] >= Lr && a[x][y + 1] < p) {       LCT::link(a[x][y + 1], p);       Seg::modify(rt, 1, n, 1, a[x][y + 1], 1);     }   }   int main() {     open( hh );     R = rd();     C = rd();     for (int i = 1; i <= R; i++) {       a[i].resize(C + 1);       for (int j = 1; j <= C; j++) b[a[i][j] = rd()] = pair<int, int>(i, j);     }     n = R * C;     Seg::build(rt, 1, n);     Lr = 1;     long long ans = 1;     for (int i = 2; i <= n; i++) {       gao(i);       pair<int, int> res = Seg::query(rt, 1, n, Lr, i);       ans += res.first == i ? res.second : 0;     }     printf( %lld n , ans);     return 0;   }