You are given an H \times W grid. The square at the top-left corner will be represented by (0, 0), and the square at the bottom-right corner will be represented by (H-1, W-1).

Of those squares, N squares (x_1, y_1), (x_2, y_2), ..., (x_N, y_N) are painted black, and the other squares are painted white.

Let the shortest distance between white squares A and B be the minimum number of moves required to reach B from A visiting only white squares, where one can travel to an adjacent square sharing a side (up, down, left or right) in one move.

Since there are H × W - N white squares in total, there are _{(H×W-N)}C_2 ways to choose two of the white squares.

For each of these _{(H×W-N)}C_2 ways, find the shortest distance between the chosen squares, then find the sum of all those distances, modulo 1 000 000 007=10^9+7.

Constraints

* 1 \leq H, W \leq 10^6
* 1 \leq N \leq 30
* 0 \leq x_i \leq H-1
* 0 \leq y_i \leq W-1
* If i \neq j, then either x_i \neq x_j or y_i \neq y_j.
* There is at least one white square.
* For every pair of white squares A and B, it is possible to reach B from A visiting only white squares.

Input

Input is given from Standard Input in the following format:


H W
N
x_1 y_1
x_2 y_2
:
x_N y_N


Output

Print the sum of the shortest distances, modulo 10^9+7.

Examples

Input

2 3
1
1 1


Output

20


Input

2 3
1
1 2


Output

16


Input

3 3
1
1 1


Output

64


Input

4 4
4
0 1
1 1
2 1
2 2


Output

268


Input

1000000 1000000
1
0 0


Output

333211937
#ifndef __clang__
#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"
#endif
#ifdef ONLINE_JUDGE
#define NDEBUG 1
#endif
#include <stdio.h>
#include <bits/stdc++.h>

#define FOR(i, n)     for(lli i = 0; i < (lli)(n); ++i)
#define FORU(i, j, k) for(lli i = (j); i <= (lli)(k); ++i)
#define FORD(i, j, k) for(lli i = (j); i >= (lli)(k); --i)

#define SQ(x) ((x)*(x))

#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back

using namespace std;

template<typename... As>
struct tpl : public std::tuple<As...> {
  using std::tuple<As...>::tuple;
  tpl(){}
  tpl(std::tuple<As...> const& b) { std::tuple<As...>::operator=(b); }

  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type const&
  x() const { return get<0>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<0, T>::type&
  x() { return get<0>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type const&
  y() const { return get<1>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<1, T>::type&
  y() { return get<1>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type const&
  z() const { return get<2>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<2, T>::type&
  z() { return get<2>(*this); }

  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type const&
  w() const { return get<3>(*this); }
  template<typename T = tuple<As...> >
  typename tuple_element<3, T>::type&
  w() { return get<3>(*this); }
};

using lli   = long long int;
using llu   = long long unsigned;

using pii   = tpl<lli, lli>;
using piii  = tpl<lli, lli, lli>;
using piiii = tpl<lli, lli, lli, lli>;
using vi    = vector<lli>;
using vii   = vector<pii>;
using viii  = vector<piii>;
using vvi   = vector<vi>;
using vvii  = vector<vii>;
using vviii = vector<viii>;

template<class T>
using min_queue = priority_queue<T, vector<T>, greater<T> >;
template<class T>
using max_queue = priority_queue<T>;

template<size_t... I>
struct my_index_sequence {
  using type = my_index_sequence;
  static constexpr array<size_t, sizeof...(I)> value = { {I...} };
};

namespace my_index_sequence_detail {
  template<typename I, typename J> struct concat;
  template<size_t... I, size_t... J>
  struct concat<my_index_sequence<I...>, my_index_sequence<J...> > :
    my_index_sequence<I..., (sizeof...(I)+J)...> { };
  template<size_t N> struct make_index_sequence :
    concat<typename make_index_sequence<N/2>::type, typename make_index_sequence<N-N/2>::type>::type { };
  template <> struct make_index_sequence<0> : my_index_sequence<>{};
  template <> struct make_index_sequence<1> : my_index_sequence<0>{};
}

template<class... A>
using my_index_sequence_for = typename my_index_sequence_detail::make_index_sequence<sizeof...(A)>::type;

template<class T, size_t... I>
void print_tuple(ostream& s, T const& a, my_index_sequence<I...>){
  using swallow = int[];
  (void)swallow{0, (void(s << (I == 0? "" : ", ") << get<I>(a)), 0)...};
}

template<class T>
ostream& print_collection(ostream& s, T const& a);
template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a);
template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a);
template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a);

template<class T, size_t I>
ostream& operator<<(ostream& s, array<T, I> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, vector<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, multimap<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, multiset<T> const& a) { return print_collection(s, a); }
template<class T, class U>
ostream& operator<<(ostream& s, map<T, U> const& a) { return print_collection(s, a); }
template<class T>
ostream& operator<<(ostream& s, set<T> const& a) { return print_collection(s, a); }

template<class T>
ostream& print_collection(ostream& s, T const& a){
  s << '[';
  for(auto it = begin(a); it != end(a); ++it){
    s << *it;
    if(it != prev(end(a))) s << " ";
  }
  return s << ']';
}

template<class... A>
ostream& operator<<(ostream& s, tpl<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class... A>
ostream& operator<<(ostream& s, tuple<A...> const& a){
  s << '(';
  print_tuple(s, a, my_index_sequence_for<A...>{});
  return s << ')';
}

template<class A, class B>
ostream& operator<<(ostream& s, pair<A, B> const& a){
  return s << "(" << get<0>(a) << ", " << get<1>(a) << ")";
}

//------------------------------------------------------------------------------

const lli MOD = 1e9+7;

const int N = 2e6;
bool A[N];
bool B[N];

lli R[100], C[100];
lli WR[100], WC[100];
bool E[100][100];
bool V[100][100];
lli D[100][100];

const lli dx[4] = {1,-1,0,0};
const lli dy[4] = {0,0,1,-1};

int main(){
  ios::sync_with_stdio(0); cin.tie(0);
  lli n,m; cin>>n>>m;
  vii ps;
  vvi xs(n), ys(m);
  lli np; cin>>np;
  FOR(i,np) {
    lli x,y; cin>>x>>y;
    A[x]=1; B[y]=1;
    xs[x].pb(y); ys[y].pb(x);
    ps.pb(mt(x,y));
  }
  lli tot = (n*m - np) % MOD;
  lli ans = 0;
  lli nr = -1, nc = -1;
  FOR(i,100) WR[i]=WC[i] = -1;
  { lli l = 0;
    FOR(i,n) {
      l %= MOD;
      if(A[i]) {
        nr++; R[nr] = 1; WR[nr] = i;
        l += m - xs[i].size();
      } else if(i==0 || A[i-1]) {
        nr++; R[nr] = 1; l += m;
      } else {
        R[nr]++;
        (ans += (l * (tot-l+MOD)) % MOD) %= MOD;
        l += m;
      }
    }
  }
  { lli l = 0;
    FOR(j,m) {
      l %= MOD;
      if(B[j]) {
        nc++; C[nc] = 1; WC[nc] = j;
        l += n - ys[j].size();
      } else if(j==0 || B[j-1]) {
        nc++; C[nc] = 1; l += n;
      } else {
        C[nc]++;
        (ans += (l * (tot-l+MOD)) % MOD) %= MOD;
        l += n;
      }
    }
  }
  nr++; nc++;
  FOR(i,nr) FOR(j,nc) { E[i][j] = 1; for(auto p : ps) if(p == mt(WR[i],WC[j])) E[i][j] = 0; }
  FOR(i,nr) FOR(j,nc) if(E[i][j]) {
    FOR(x,nr) FOR(y,nc) { V[x][y] = 0; D[x][y] = (1<<20); }
    queue<pii> Q; Q.push(mt(i,j)); D[i][j] = 0; V[i][j] = 1;
    while(!Q.empty()) {
      lli x,y; tie(x,y) = Q.front(); Q.pop();
      // cout << mt(i,j) << " " << mt(x,y) << " " << D[x][y] << endl;
      if(mt(i,j) < mt(x,y)) (ans += D[x][y] * R[i] % MOD * C[j] % MOD * R[x] % MOD * C[y] % MOD) %= MOD;
      FOR(d,4) {
        lli x_ = x+dx[d], y_ = y+dy[d];
        if(x_<0||x_>=nr||y_<0||y_>=nc) continue;
        if(!E[x_][y_]) continue;
        if(V[x_][y_]) continue;
        V[x_][y_] = 1;
        D[x_][y_] = D[x][y]+1;
        Q.push(mt(x_,y_));
      }
    }
  }
  cout << ans << endl;
  return 0;
}
