← Home
package main

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

const P = 1000000007
const P64 = int64(P)

var inv [5000005]int32
var f [5000005]int32

func initInv() {
	inv[1] = 1
	for i := 2; i <= 5000000; i++ {
		inv[i] = int32((P64 - (P64/int64(i))*int64(inv[P%i])%P64) % P64)
	}
}

func power(base, exp int64) int64 {
	res := int64(1)
	base %= P64
	for exp > 0 {
		if exp%2 == 1 {
			res = (res * base) % P64
		}
		base = (base * base) % P64
		exp /= 2
	}
	return res
}

func getC3(M, n int) (int64, int64, int64) {
	if M < 0 {
		return 0, 0, 0
	}
	f[0] = 1
	if n >= 1 {
		f[1] = int32((M + 4) % P)
	}
	for k := 1; k < n; k++ {
		term1 := (int64(3*k+M+4) * int64(f[k])) % P64
		term1 = (term1 * int64(inv[k+1])) % P64
		term2 := (2 * int64(f[k-1])) % P64
		next := (term1 - term2) % P64
		if next < 0 {
			next += P64
		}
		f[k+1] = int32(next)
	}

	factor := (int64(M+1) * power(2, int64(M))) % P64
	var c_n, c_n1, c_n2 int64
	if n >= 0 {
		c_n = (factor * int64(f[n])) % P64
	}
	if n-1 >= 0 {
		c_n1 = (factor * int64(f[n-1])) % P64
	}
	if n-2 >= 0 {
		c_n2 = (factor * int64(f[n-2])) % P64
	}
	return c_n, c_n1, c_n2
}

func main() {
	initInv()
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	t, _ := strconv.Atoi(scanner.Text())

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	for i := 0; i < t; i++ {
		scanner.Scan()
		n, _ := strconv.Atoi(scanner.Text())
		scanner.Scan()
		m, _ := strconv.Atoi(scanner.Text())

		if n > m {
			n, m = m, n
		}

		c_m_n, c_m_n1, c_m_n2 := getC3(m, n)
		c_m1_n, c_m1_n1, c_m1_n2 := getC3(m-1, n)
		c_m2_n, c_m2_n1, c_m2_n2 := getC3(m-2, n)

		d_n := (c_m_n - 2*c_m1_n + c_m2_n) % P64
		if d_n < 0 {
			d_n += P64
		}
		d_n1 := (c_m_n1 - 2*c_m1_n1 + c_m2_n1) % P64
		if d_n1 < 0 {
			d_n1 += P64
		}
		d_n2 := (c_m_n2 - 2*c_m1_n2 + c_m2_n2) % P64
		if d_n2 < 0 {
			d_n2 += P64
		}

		ans := (d_n - 2*d_n1 + d_n2) % P64
		if ans < 0 {
			ans += P64
		}

		fmt.Fprintln(out, ans)
	}
}