#include<bits/stdc++.h>
#include<fstream>
using namespace std;
#define sz(a) (int)a.size()
#define ALL(v) v.begin(), v.end()
#define ALLR(v) v.rbegin(), v.rend()
#define ll long long
#define pb push_back
#define forr(i, a, b) for(int i = a; i < b; i++)
#define dorr(i, a, b) for(int i = a; i >= b; i--)
#define ld long double
#define vt vector
#include<fstream>
#define fi first
#define se second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mpp make_pair
const ld PI = 3.14159265359, prec = 1e-9;;
//using u128 = __uint128_t;
const int cox[4] = {1, 0, -1, 0};
#include <vector>
const int coy[4] = {0, -1, 0, 1};
const ll mod = 1e9 + 7, pr = 31;
const int mxn = 2e5 + 5, mxd = 250 * 250, sq = 100, mxv = 5e4 + 1;
//const int base = (1 <<18);
const ll inf = 1e18 + 5, neg = -69420, inf2 = 1e14;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// have fun!
/*
#include <vector>
static const int buf_size = 4096;
inline int getChar() {
	static char buf[buf_size];
	static int len = 0, pos = 0;
	if (pos == len) {
		pos = 0;
		len = fread(buf, 1, buf_size, stdin);
	}
	if (pos == len)
		return -1;
	return buf[pos++];
}
inline int readChar() {
	int c = getChar();
	while (c <= 32)
		c = getChar();
	return c;
}
inline int readInt() {
	int x; cin >> x;
	return x;
}
*/
#include <vector>
const int N = 2505;
const ll base = (1 << 12);
vt<int>seg_row[N], seg_col[N];
vt<pii>range_col[N], range_row[N];
pair<int, int>row[N][N], col[N][N];
int n, m;
int get(vt<int>&seg, int ob){
    int id = lower_bound(ALL(seg), ob) - seg.begin();
    if(id == sz(seg) || seg[id] != ob)return(-1);
    return(id);
}
ll HASH(ll a, ll b, ll c, ll d){
    return((((a * base) + b) * base + c) * base + d);
}
int HASH(pii a){
    return(a.fi * base + a.se);
}
long long count_rectangles(std::vector<std::vector<int> > a){
    n = sz(a); m = sz(a[0]);
    for(int i = 0; i < n; i++){
        stack<int>st;
        for(int j = 0; j < m; j++){
            while(sz(st) && a[i][st.top()] <= a[i][j])st.pop();
            row[i][j].fi = ((sz(st) == 0) ? 0 : st.top() + 1);
            st.push(j);
        }
        while(sz(st))st.pop();
        for(int j = m - 1; j >= 0; j--){
            while(sz(st) && a[i][st.top()] <= a[i][j])st.pop();
            row[i][j].se = ((sz(st) == 0) ? m - 1 : st.top() - 1);
            st.push(j);
        }
    }
    for(int j = 0; j < m; j++){
        stack<int>st;
        for(int i = 0; i < n; i++){
            while(sz(st) && a[st.top()][j] <= a[i][j])st.pop();
            col[i][j].fi = ((sz(st) == 0) ? 0 : st.top() + 1);
            st.push(i);
        }
        while(sz(st))st.pop();
        for(int i = n - 1; i >= 0; i--){
            while(sz(st) && a[st.top()][j] <= a[i][j])st.pop();
            col[i][j].se = ((sz(st) == 0) ? n - 1 : st.top() - 1);
            st.push(i);
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            seg_row[i].pb(HASH(row[i][j])); seg_col[j].pb(HASH(col[i][j]));
        }
    }
    for(int i = 0; i < n; i++){
        sort(ALL(seg_row[i])); seg_row[i].resize(unique(ALL(seg_row[i])) - seg_row[i].begin());
        range_row[i].resize(sz(seg_row[i]));
    }
    for(int i = 0; i < m; i++){
        sort(ALL(seg_col[i])); seg_col[i].resize(unique(ALL(seg_col[i])) - seg_col[i].begin());
        range_col[i].resize(sz(seg_col[i]));
    }
    for(int i = 0; i < n; i++){
        for(int j = 0; j < sz(seg_row[i]); j++){
            if(i == 0){
                range_row[i][j].fi = 0; continue;
            }
            int id = get(seg_row[i - 1], seg_row[i][j]);
            if(id == -1){
                range_row[i][j].fi = i;
            }else{
                range_row[i][j].fi = range_row[i - 1][id].fi;
            }
        }
    }
    for(int i = n - 1; i >= 0; i--){
        for(int j = 0; j < sz(seg_row[i]); j++){
            if(i == n - 1){
                range_row[i][j].se = n - 1; continue;
            }
            int id = get(seg_row[i + 1], seg_row[i][j]);
            if(id == -1){
                range_row[i][j].se = i;
            }else{
                range_row[i][j].se = range_row[i + 1][id].se;
            }
        }
    }
    for(int i = 0; i < m; i++){
        for(int j = 0; j < sz(seg_col[i]); j++){
            if(i == 0){
                range_col[i][j].fi = 0; continue;
            }
            int id = get(seg_col[i - 1], seg_col[i][j]);
            if(id == -1){
                range_col[i][j].fi = i;
            }else{
                range_col[i][j].fi = range_col[i - 1][id].fi;
            }
        }
    }
    for(int i = m - 1; i >= 0; i--){
        for(int j = 0; j < sz(seg_col[i]); j++){
            if(i == m - 1){
                range_col[i][j].se = m - 1; continue;
            }
            int id = get(seg_col[i + 1], seg_col[i][j]);
            if(id == -1){
                range_col[i][j].se = i;
            }else{
                range_col[i][j].se = range_col[i + 1][id].se;
            }
        }
    }
    vt<ll>res;
    for(int i = 1; i < n - 1; i++){
        for(int j = 1; j < m - 1; j++){
            int idr = lower_bound(ALL(seg_row[i]), HASH(row[i][j])) - seg_row[i].begin();
            int idl = lower_bound(ALL(seg_col[j]), HASH(col[i][j])) - seg_col[j].begin();
            if(row[i][j].fi != 0 && row[i][j].se != m - 1 && range_row[i][idr].fi <= col[i][j].fi && range_row[i][idr].se >= col[i][j].se){
                if(col[i][j].fi != 0 && col[i][j].se != n - 1 && range_col[j][idl].fi <= row[i][j].fi && range_col[j][idl].se >= row[i][j].se){
                    res.pb(HASH(row[i][j].fi, row[i][j].se, col[i][j].fi, col[i][j].se));
                }
            }
        }
    }
    sort(ALL(res)); res.resize(unique(ALL(res)) - res.begin());
    return(sz(res));
}
/*
int main() {
	int n = readInt();
	int m = readInt();
	vector<vector<int> > a(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
		    a[i][j] = readInt();
		}
	}
	fclose(stdin);
	long long result = count_rectangles(a);
	printf("%lld\n", result);
	fclose(stdout);
	return 0;
}
/*
6 5
4 8 7 5 6
7 4 10 3 5
9 7 20 14 2
9 14 7 3 6
5 7 5 2 7
4 5 13 5 6
*/
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |