#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <vector>

#define debug(...) fprintf(stderr, __VA_ARGS__)

#ifndef AT_HOME
#define getchar() IO::myGetchar()
#define putchar(x) IO::myPutchar(x)
#endif

namespace IO {
	static const int IN_BUF = 1 << 23, OUT_BUF = 1 << 23;

	inline char myGetchar() {
		static char buf[IN_BUF], *ps = buf, *pt = buf;
		if (ps == pt) {
			ps = buf, pt = buf + fread(buf, 1, IN_BUF, stdin);
		}
		return ps == pt ? EOF : *ps++;
	}

	template<typename T>
	inline bool read(T &x) {
		bool op = 0;
		char ch = getchar();
		x = 0;
		for (; !isdigit(ch) && ch != EOF; ch = getchar()) {
			op ^= (ch == '-');
		}
		if (ch == EOF) {
			return false;
		}
		for (; isdigit(ch); ch = getchar()) {
			x = x * 10 + (ch ^ '0');
		}
		if (op) {
			x = -x;
		}
		return true;
	}

	inline int readStr(char *s) {
		int n = 0;
		char ch = getchar();
		for (; isspace(ch) && ch != EOF; ch = getchar())
			;
		for (; !isspace(ch) && ch != EOF; ch = getchar()) {
			s[n++] = ch;
		}
		s[n] = '\0';
		return n;
	}

	inline void myPutchar(char x) {
		static char pbuf[OUT_BUF], *pp = pbuf;
		struct _flusher {
			~_flusher() {
				fwrite(pbuf, 1, pp - pbuf, stdout);
			}
		};
		static _flusher outputFlusher;
		if (pp == pbuf + OUT_BUF) {
			fwrite(pbuf, 1, OUT_BUF, stdout);
			pp = pbuf;
		}
		*pp++ = x;
	}

	template<typename T>
	inline void print_(T x) {
		if (x == 0) {
			putchar('0');
			return;
		}
		std::vector<int> num;
		if (x < 0) {
			putchar('-');
			x = -x;
		}
		for (; x; x /= 10) {
			num.push_back(x % 10);
		}
		while (!num.empty()) {
			putchar(num.back() ^ '0');
			num.pop_back();
		}
	}

	template<typename T>
	inline void print(T x, char ch = '\n') {
		print_(x);
		putchar(ch);
	}

	inline void printStr_(const char *s, int n = -1) {
		if (n == -1) {
			n = strlen(s);
		}
		for (int i = 0; i < n; ++i) {
			putchar(s[i]);
		}
	}

	inline void printStr(const char *s, int n = -1, char ch = '\n') {
		printStr_(s, n);
		putchar(ch);
	}
}
using namespace IO;

const int N = 105, M = 1000005;
const int P = 1000000007, Inv2 = (P + 1) / 2;

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

int n, m, k, x[N], y[N];
int cntx[M], idx[M], wx[M], cnty[M], idy[M], wy[M];
int a[N][N], ans;

void solve(int *cnt, int *id, int *w, int n, int m) {
	int now = 0, idx = 0;
	for (int i = 0; i < n - 1; ++i) {
		now = (now + m - cnt[i]) % P;
		if (cnt[i] || cnt[i + 1]) {
			id[i] = idx++;
			continue;
		}
		int t = (1ll * n * m - k - now) % P;
		ans = (ans + 2ll * now * t) % P;
		id[i] = idx;
	}
	id[n - 1] = idx++;
	for (int i = 0; i < n; ++i) {
		++w[id[i]];
	}
}

int bfs(int x, int y) {
	static int dis[N][N];
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			dis[i][j] = P;
		}
	}
	std::vector<std::pair<int, int>> Q;
	int res = 0;
	dis[x][y] = 0, Q.push_back({x, y});
	for (int i = 0; i < (int)Q.size(); ++i) {
		int x = Q[i].first, y = Q[i].second;
		res = (res + 1ll * a[x][y] * dis[x][y]) % P;
		for (int k = 0; k < 4; ++k) {
			int nx = x + dx[k], ny = y + dy[k];
			if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
				continue;
			}
			if (a[nx][ny] == -1 || dis[nx][ny] < P) {
				continue;
			}
			dis[nx][ny] = dis[x][y] + 1;
			Q.push_back({nx, ny});
		}
	}
	return res;
}

int main() {
	read(n), read(m), read(k);
	for (int i = 0; i < k; ++i) {
		read(x[i]), read(y[i]);
		++cntx[x[i]], ++cnty[y[i]];
	}
	solve(cntx, idx, wx, n, m);
	solve(cnty, idy, wy, m, n);
	n = idx[n - 1] + 1;
	m = idy[m - 1] + 1;
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			a[i][j] = 1ll * wx[i] * wy[j] % P;
		}
	}
	for (int i = 0; i < k; ++i) {
		a[idx[x[i]]][idy[y[i]]] = -1;
	}
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			if (a[i][j] != -1) {
				ans = (ans + 1ll * a[i][j] * bfs(i, j)) % P;
			}
		}
	}
	print(1ll * ans * Inv2 % P);
}


Measured memory_bytes: 11176