Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	io := NewIo()
	defer io.Flush()
	for {
		d, w := io.NextInt(), io.NextInt()
		if d == 0 {
			break
		}
		e := make([][]int, d)
		for i := 0; i < d; i++ {
			e[i] = make([]int, w)
			for j := 0; j < w; j++ {
				e[i][j] = io.NextInt()
			}
		}
		ans := 0
		for i := 0; i < d-2; i++ {
			for j := 0; j < w-2; j++ {
				for k := i + 2; k < d; k++ {
					for l := j + 2; l < w; l++ {
						ans = intMax(vol(e, i, j, k, l), ans)
					}
				}
			}
		}
		io.Println(ans)
	}
}

func vol(e [][]int, a, b, c, d int) int {
	outer := 10
	for i := a; i <= c; i++ {
		outer = intMin(e[i][b], outer)
		outer = intMin(e[i][d], outer)
	}
	for j := b; j <= d; j++ {
		outer = intMin(e[a][j], outer)
		outer = intMin(e[c][j], outer)
	}
	a++
	b++
	vol := 0
	for i := a; i < c; i++ {
		for j := b; j < d; j++ {
			if e[i][j] >= outer {
				return 0
			}
			vol += outer - e[i][j]
		}
	}
	return vol
}

func intMax(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func intMin(a, b int) int {
	if a > b {
		return b
	}
	return a
}

// I/O template
type Io struct {
	reader    *bufio.Reader
	writer    *bufio.Writer
	tokens    []string
	nextToken int
}

func NewIo() *Io {
	return &Io{
		reader: bufio.NewReader(os.Stdin),
		writer: bufio.NewWriter(os.Stdout),
	}
}

func (io *Io) Flush() {
	err := io.writer.Flush()
	if err != nil {
		panic(err)
	}
}

func (io *Io) NextLine() string {
	var buff []byte
	for {
		line, isPrefix, err := io.reader.ReadLine()
		if err != nil {
			panic(err)
		}
		buff = append(buff, line...)
		if !isPrefix {
			break
		}
	}
	return string(buff)
}

func (io *Io) Next() string {
	for io.nextToken >= len(io.tokens) {
		line := io.NextLine()
		io.tokens = strings.Fields(line)
		io.nextToken = 0
	}
	s := io.tokens[io.nextToken]
	io.nextToken++
	return s
}

func (io *Io) NextInt() int {
	i, err := strconv.Atoi(io.Next())
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) NextFloat() float64 {
	i, err := strconv.ParseFloat(io.Next(), 64)
	if err != nil {
		panic(err)
	}
	return i
}

func (io *Io) Println(a ...interface{}) {
	fmt.Fprintln(io.writer, a...)
}

func (io *Io) Printf(format string, a ...interface{}) {
	fmt.Fprintf(io.writer, format, a...)
}

func (io *Io) PrintIntSlice(a []int) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func (io *Io) PrintStringSlice(a []string) {
	b := []interface{}{}
	for _, x := range a {
		b = append(b, x)
	}
	io.Println(b...)
}

func Log(name string, value interface{}) {
	fmt.Fprintf(os.Stderr, "%s=%+v\n", name, value)
}

func ExampleIo() {
	io := NewIo()
	defer io.Flush()
	a := make([]int, 0, 3)
	a[0], a[1], a[2] = io.NextInt(), io.NextInt(), io.NextInt()
	io.Println(a)
	io.PrintIntSlice(a)
	Log("io", a)
}

C++: #include <bits/stdc++.h>
using namespace std; 
int d,w;
int main(){
	while(scanf(" %d%d",&d,&w)==2&&w!=0&&d!=0){
		int tbl[12][12]={};
		int ans=0;
		for(int i=1;i<=d;i++){	//d代表行数 
			for(int j=1;j<=w;j++){	//w代表列数 
				cin>>tbl[i][j];	//x,y仍然是，x代表列数，y代表行数,横坐标写在后面，纵坐标写在前面 
			}
		}
		//枚举所有矩形，每次枚举记录边界的最小值和区域的最大值，不满足则break，满足就记录面积
		//取max，至遍历完，关键在于边界的遍历注意坐标。
		//不妨每次枚举左上端点以及深度和宽度，则决定了一个矩形
		for(int i=1;i<=d-2;i++){	//(j,i)为枚举的左上端点 
			for(int j=1;j<=w-2;j++){
				for(int deep=3;deep+i-1<=d;deep++){	//枚举深度和宽度 
					for(int wid=3;wid+j-1<=w;wid++){
						//到此处矩形已经决定了
						//遍历边界
						int y,x;
						int outmii=100,inmiv=-1;
						for(x=0;x<wid;x++)	//水平向右遍历
						{
							if(tbl[i][x+j]<outmii) outmii=tbl[i][x+j];
							if(tbl[i+deep-1][x+j]<outmii) outmii=tbl[i+deep-1][x+j];
						}
						for(y=0;y<deep;y++)
						{
							if(tbl[y+i][j]<outmii) outmii = tbl[y+i][j];
							if(tbl[y+i][j+wid-1]<outmii) outmii = tbl[y+i][j+wid-1];
						}
						
						//遍历区域
						int sum=0;
						for(int x=1;x<wid-1;x++){
							for(int y=1;y<deep-1;y++){
								if(tbl[y+i][x+j]>inmiv) inmiv = tbl[y+i][x+j];
								sum+=outmii-tbl[y+i][x+j];
							}
						}
						
					//	if(i==1&&j==1&&wid==5&&deep==3){
					//		cout<<sum<<" "<<outmii<<" "<<inmiv<<endl;
					//	}
						
						if(inmiv >= outmii) continue;
						else{
							ans=max(ans,sum);
						} 
					}
				}
			}
		} 
		cout<<ans<<endl;
	}
} 

/*
3 3
2 3 2
2 1 2
2 3 1
3 5
3 3 4 3 3
3 1 0 2 3
3 3 4 3 2
7 7
1 1 1 1 1 0 0
1 0 0 0 1 0 0
1 0 1 1 1 1 1
1 0 1 0 1 0 1
1 1 1 1 1 0 1
0 0 1 0 0 0 1
0 0 1 1 1 1 1
6 6
1 1 1 1 2 2
1 0 0 2 0 2
1 0 0 2 0 2
3 3 3 9 9 9
3 0 0 9 0 9
3 3 3 9 9 9
0 0
*/

C++: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef pair<ll,ll> mp;
ll inf =  1e9;


int main(){
 while(1){
 ll h,w;
 cin>>h>>w;
 if( h==0 && w==0 ) break;
 vector<vector<ll> > e(h+2,vector<ll>(w+2,0) );
 for(ll i=1;i<=h;i++)for(ll j=1;j<=w;j++) cin>>e[i][j];
 ll res = 0;
 for(ll l=1;l<=h;l++){
  for(ll u=l+2;u<=h;u++){
   for(ll r=1;r<=w;r++){
    for(ll le=r+2;le<=w;le++){
     ll side = inf;
     ll inner = 0;
     for(ll i=l+1;i<u;i++)for(ll j=r+1;j<le;j++) inner = max( inner , e[i][j] );

     for(ll i=l;i<=u;i++) side = min( side , min( e[i][r] , e[i][le] ) );
     for(ll i=r;i<=le;i++) side = min( side , min( e[l][i] , e[u][i] ) );

     if( inner < side ){
      ll cnt = 0;
     for(ll i=l+1;i<u;i++)for(ll j=r+1;j<le;j++) cnt += side - e[i][j];

      res = max( res , cnt );
     }
    }
   }
  }
 }

 cout<<res<<endl;

 }
    return 0;
}

C++: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "math.h"
#include "utility"
#include "string"
#include "map"
#include "unordered_map"
#include "iomanip"
#include "random"

using namespace std;
const long long int MOD = 1000000007;

long long int power(long long int x, long long int n, long long int M) {
	long long int tmp = 1;

	if (n > 0) {
		tmp = power(x, n / 2, M);
		if (n % 2 == 0) tmp = (tmp*tmp) % M;
		else tmp = (((tmp*tmp) % M)*x) % M;
	}
	return tmp;
}

long long int N, M, K, Q, W, H, L, R;
long long int ans;


int main() {
	ios::sync_with_stdio(false);
	cin >> H >> W;
	while (H) {
		int num[10][10] = {};
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++)cin >> num[i][j];
		}
		ans = 0;
		for (int i = 0; i < H; i++) {
			for (int j = i + 2; j < H; j++) {
				for (int k = 0; k < W; k++) {
					for (int l = k + 2; l < W; l++) {
						int box = 0;
						int edge = 10;
						int pond = 0;
						for (int m = i; m <= j; m++) {
							edge = min(edge, num[m][k]);
							edge = min(edge, num[m][l]);
						}
						for (int m = k; m <= l; m++) {
							edge = min(edge, num[i][m]);
							edge = min(edge, num[j][m]);
						}

						for (int m = i + 1; m < j; m++) {
							for (int n = k + 1; n < l; n++) {
								pond = max(pond, num[m][n]);
								box += edge - num[m][n];
							}
						}
					//	cout << edge << " " << pond << endl;
						if (edge > pond) {
							ans = max((int)ans, box);
						}
					}
				}
			}
		}
		cout << ans << endl;
		cin >> H >> W;
	}
	return 0;
}