Problem:
Score : 500 points

Problem Statement

On a two-dimensional plane, there are m lines drawn parallel to the x axis, and n lines drawn parallel to the y axis.
Among the lines parallel to the x axis, the i-th from the bottom is represented by y = y_i.
Similarly, among the lines parallel to the y axis, the i-th from the left is represented by x = x_i.

For every rectangle that is formed by these lines, find its area, and print the total area modulo 10^9+7.

That is, for every quadruple (i,j,k,l) satisfying 1\leq i < j\leq n and 1\leq k < l\leq m, find the area of the rectangle formed by the lines x=x_i, x=x_j, y=y_k and y=y_l, and print the sum of these areas modulo 10^9+7.

Constraints

2 \leq n,m \leq 10^5

-10^9 \leq x_1 < ... < x_n \leq 10^9

-10^9 \leq y_1 < ... < y_m \leq 10^9

x_i and y_i are integers.

Input

Input is given from Standard Input in the following format:

n m
x_1 x_2 ... x_n
y_1 y_2 ... y_m

Output

Print the total area of the rectangles, modulo 10^9+7.

Sample Input 1

3 3
1 3 4
1 3 6

Sample Output 1

60

The following figure illustrates this input:

The total area of the nine rectangles A, B, ..., I shown in the following figure, is 60.

Sample Input 2

6 5
-790013317 -192321079 95834122 418379342 586260100 802780784
-253230108 193944314 363756450 712662868 735867677

Sample Output 2

835067060

Solution in Rust (1.15.1) (judge verdict: Accepted)

#![allow(unused_imports, unused_macros, dead_code)]

macro_rules! min {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| min!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = min!($($ys),*);
        if $x < t { $x } else { t }
    }}
}
macro_rules! max {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        it.next().map(|z| it.fold(z, |x, y| max!(x, y)))
    }};
    ($x:expr) => ($x);
    ($x:expr, $($ys:expr),*) => {{
        let t = max!($($ys),*);
        if $x > t { $x } else { t }
    }}
}
macro_rules! ewriteln {
    ($($args:expr),*) => { let _ = writeln!(&mut std::io::stderr(), $($args),*); };
}
macro_rules! trace {
    ($x:expr) => { ewriteln!(">>> {} = {:?}", stringify!($x), $x) };
    ($($xs:expr),*) => { trace!(($($xs),*)) }
}
macro_rules! put {
    (.. $x:expr) => {{
        let mut it = $x.iter();
        if let Some(x) = it.next() { print!("{}", x); }
        for x in it { print!(" {}", x); }
        println!("");
    }};
    ($x:expr) => { println!("{}", $x) };
    ($x:expr, $($xs:expr),*) => { print!("{} ", $x); put!($($xs),*) }
}

const M: i64 = 1_000_000_007;

fn main() {
    let mut sc = Scanner::new();
    let h: usize = sc.cin();
    let w: usize = sc.cin();
    let mut xs: Vec<i64> = sc.vec(h);
    let mut ys: Vec<i64> = sc.vec(w);
    xs.sort(); ys.sort();
    {
        let mut a = vec![0i64; h - 1];
        let mut b = vec![0i64; w - 1];
        for i in 0..h - 1 { a[i] = xs[i + 1] - xs[i]; }
        for i in 0..w - 1 { b[i] = ys[i + 1] - ys[i]; }
        let mut dist = ModInt::new(0, M);
        let mut ans = ModInt::new(0, M);
        for i in 0..h - 1 {
            dist += ModInt::new((i + 1) as i64 * (h - i - 1) as i64, M) * (a[i] as i64);
        }
        for j in 0..w - 1 {
            ans += dist * ModInt::new((j + 1) as i64 * (w - j - 1) as i64, M) * (b[j] as i64);
        }
        put!(ans);
    }
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct ModInt(i64, i64);  // (residual, modulo)
impl ModInt {
    fn new(residual: i64, modulo: i64) -> ModInt {
        if residual >= modulo { ModInt(residual % modulo, modulo) }
        else if residual < 0 { ModInt((residual % modulo) + modulo, modulo) }
        else { ModInt(residual, modulo) }
    }
    fn unwrap(self) -> i64 { self.0 }
    fn inv(self) -> Self {
        fn exgcd(r0: i64, a0: i64, b0: i64, r: i64, a: i64, b: i64)
                -> (i64, i64, i64) {
            if r > 0 {
                exgcd(r, a, b, r0 % r, a0 - r0 / r * a, b0 - r0 / r * b)
            } else {
                (a0, b0, r0)
            }
        }
        let (a, _, r) = exgcd(self.0, 1, 0, self.1, 0, 1);
        if r != 1 { panic!("{:?} has no inverse!", self); }
        ModInt(((a % self.1) + self.1) % self.1, self.1)
    }
    fn pow(self, n: i64) -> Self {
        if n < 0 {
            self.pow(-n).inv()
        } else if n == 0 {
            ModInt(1, self.1)
        } else if n == 1 {
            self
        } else {
            let mut x = (self * self).pow(n / 2);
            if n % 2 == 1 { x *= self }
            x
        }
    }
}
impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}
impl std::ops::Neg for ModInt {
    type Output = Self;
    fn neg(self) -> Self {
        if self.0 == 0 { return self }
        ModInt(self.1 - self.0, self.1)
    }
}
impl std::ops::Add<i64> for ModInt {
    type Output = Self;
    fn add(self, other: i64) -> Self { ModInt::new(self.0 + other, self.1) }
}
impl std::ops::Add for ModInt {
    type Output = Self;
    fn add(self, other: ModInt) -> Self { self + other.0 }
}
impl std::ops::Add<ModInt> for i64 {
    type Output = ModInt;
    fn add(self, other: ModInt) -> ModInt { other + self }
}
impl std::ops::AddAssign<i64> for ModInt {
    fn add_assign(&mut self, other: i64) { self.0 = ModInt::new(self.0 + other, self.1).0; }
}
impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, other: ModInt) { *self += other.0; }
}
impl std::ops::Sub<i64> for ModInt {
    type Output = Self;
    fn sub(self, other: i64) -> Self { ModInt::new(self.0 - other, self.1) }
}
impl std::ops::Sub for ModInt {
    type Output = Self;
    fn sub(self, other: ModInt) -> Self { self - other.0 }
}
impl std::ops::Sub<ModInt> for i64 {
    type Output = ModInt;
    fn sub(self, other: ModInt) -> ModInt { ModInt::new(self - other.0, other.1) }
}
impl std::ops::SubAssign<i64> for ModInt {
    fn sub_assign(&mut self, other: i64) { self.0 = ModInt::new(self.0 - other, self.1).0; }
}
impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, other: ModInt) { *self -= other.0; }
}
impl std::ops::Mul<i64> for ModInt {
    type Output = Self;
    fn mul(self, other: i64) -> Self { ModInt::new(self.0 * other, self.1) }
}
impl std::ops::Mul for ModInt {
    type Output = Self;
    fn mul(self, other: ModInt) -> Self { self * other.0 }
}
impl std::ops::Mul<ModInt> for i64 {
    type Output = ModInt;
    fn mul(self, other: ModInt) -> ModInt { other * self }
}
impl std::ops::MulAssign<i64> for ModInt {
    fn mul_assign(&mut self, other: i64) { self.0 = ModInt::new(self.0 * other, self.1).0; }
}
impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, other: ModInt) { *self *= other.0; }
}
impl std::ops::Div for ModInt {
    type Output = Self;
    fn div(self, other: ModInt) -> Self { self * other.inv() }
}
impl std::ops::Div<i64> for ModInt {
    type Output = Self;
    fn div(self, other: i64) -> Self { self / ModInt(other, self.1) }
}
impl std::ops::Div<ModInt> for i64 {
    type Output = ModInt;
    fn div(self, other: ModInt) -> ModInt { other.inv() * self }
}
impl std::ops::DivAssign for ModInt {
    fn div_assign(&mut self, other: ModInt) { self.0 = (self.clone() / other).0; }
}
impl std::ops::DivAssign<i64> for ModInt {
    fn div_assign(&mut self, other: i64) { *self /= ModInt(other, self.1); }
}

use std::io::{self, Write};
use std::str::FromStr;
use std::collections::VecDeque;

struct Scanner { stdin: io::Stdin, buffer: VecDeque<String>, }
impl Scanner {
    fn new() -> Self { Scanner { stdin: io::stdin(), buffer: VecDeque::new() } }
    fn cin<T: FromStr>(&mut self) -> T {
        while self.buffer.len() == 0 {
            let mut line = String::new();
            let _ = self.stdin.read_line(&mut line);
            for w in line.split_whitespace() {
                self.buffer.push_back(String::from(w));
            }
        }
        self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
    }
    fn chars(&mut self) -> Vec<char> { self.cin::<String>().chars().collect() }
    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> { (0..n).map(|_| self.cin()).collect() }
}