朴素计数与去重。

先考虑有一边平行x轴的情况,底2高1或底1高2。

底2高1:先在行内选边和点再选行。底边在同一行时有n-2种选法,高所在那一行的点有n种选法。底边和高所在的行是相邻的,有m-1种可能,然后底边所在行可以和高所在行互换所以乘2。

底1高2是同理的,底边同一行内n-1种选法,高n种,底边和高的行m-2种(间距为2了),可互换就乘2。

然后再考虑有一边平行y轴的情况。可以直接互换m,n让图形旋转一下即可套用前面的结论。

所以有一边平行x轴的式子原本是这样的:(n-2)*n*2(m-1) + (n-1)*n*2(m-2)。

但是有些三角形是一边平行x轴,一边平行y轴。我们要去重。

这里去重的方法很简单:

在同一行选高的时候,只有两个点会让三角形变成直角三角形,而恰好是这两个三角形被重复计数。

那么可以直接去掉其中一个三角形,用另一个三角形的重复计数来弥补即可,这样总数就是对的。

在式子上的变化就是把高可以选n个点变成n-1个点。

见代码。

#include <bits/stdc++.h>
using namespace std;

const int mod = 1e9+7;

int main() {
    long long n,m; cin>>n>>m;
    long long ans = 0;
    ans += (n-2)*(n-1)%mod*2%mod*(m-1)%mod;
    ans += (n-1)*(n-1)%mod*2%mod*(m-2)%mod;
    swap(n,m);
    ans += (n-2)*(n-1)%mod*2%mod*(m-1)%mod;
    ans += (n-1)*(n-1)%mod*2%mod*(m-2)%mod;
    cout << ans%mod;
}
// 64 位输出请用 printf("%lld")