import java.util.Arrays; public class Main { private static void solve() { int h = ni(); int w = ni(); int k = ni(); int[][] p = new int[k][4]; for (int i = 0; i < k; i++) { p[i][0] = i; p[i][1] = ni(); p[i][2] = ni(); } Arrays.sort(p, (o1, o2) -> o1[1] == o2[1] ? o1[2] - o2[2] : o1[1] - o2[1]); for (int i = 0; i < k; i++) { p[i][3] = i; } int mod = 100000000 + 7; long[] dp = new long[1 << k]; int[][] fif = enumFIF(300000, mod); outer: for (int i = 0; i < (1 << k); i++) { long x = 1; int[] last = new int[] {0, 0, 0}; for (int j = 0; j < k; j++) { if (((i >> j) & 1) == 0) continue; int[] now = p[j]; if (last[2] > now[2]) continue outer; int dh = now[1] - last[1]; int dw = now[2] - last[2]; x *= CX(dh + dw, dh, mod, fif); x %= mod; last = p[j]; } int dh = h - last[1]; int dw = w - last[2]; x *= CX(dh + dw, dh, mod, fif); x %= mod; dp[i] = x; } for (int i = 0; i < k; i++) { for (int j = 0; j < (1 << k); j++) { if ((j & (1 << i)) != 0) { dp[j] = dp[j] + mod - dp[j ^ (1 << i)]; dp[j] %= mod; } } } Arrays.sort(p, (o1, o2) -> o1[0] - o2[0]); for (int i = 0; i < (1 << k); i++) { int x = 0; int cnt = 0; for (int j = 0; j < k; j++) { if (((i >> j) & 1) != 0) { x |= 1 << p[j][3]; cnt ++; } } if (cnt % 2 == 1) { dp[x] = mod - dp[x]; } out.println(dp[x]); } } public static long CX(long n, long r, int p, int[][] fif) { if (n < 0 || r < 0 || r > n) return 0; int np = (int) (n % p), rp = (int) (r % p); if (np < rp) return 0; if (n == 0 && r == 0) return 1; int nrp = np - rp; if (nrp < 0) nrp += p; return (long) fif[0][np] * fif[1][rp] % p * fif[1][nrp] % p * CX(n / p, r / p, p, fif) % p; } public static int[][] enumFIF(int n, int mod) { int[] f = new int[n + 1]; int[] invf = new int[n + 1]; f[0] = 1; for (int i = 1; i <= n; i++) { f[i] = (int) ((long) f[i - 1] * i % mod); } long a = f[n]; long b = mod; long p = 1, q = 0; while (b > 0) { long c = a / b; long d; d = a; a = b; b = d % b; d = p; p = q; q = d - c * q; } invf[n] = (int) (p < 0 ? p + mod : p); for (int i = n - 1; i >= 0; i--) { invf[i] = (int) ((long) invf[i + 1] * (i + 1) % mod); } return new int[][] {f, invf}; } public static void main(String[] args) { new Thread(null, new Runnable() { @Override public void run() { long start = System.currentTimeMillis(); String debug = args.length > 0 ? args[0] : null; if (debug != null) { try { is = java.nio.file.Files.newInputStream(java.nio.file.Paths.get(debug)); } catch (Exception e) { throw new RuntimeException(e); } } reader = new java.io.BufferedReader(new java.io.InputStreamReader(is), 32768); solve(); out.flush(); tr((System.currentTimeMillis() - start) + "ms"); } }, "", 64000000).start(); } private static java.io.InputStream is = System.in; private static java.io.PrintWriter out = new java.io.PrintWriter(System.out); private static java.util.StringTokenizer tokenizer = null; private static java.io.BufferedReader reader; public static String next() { while (tokenizer == null || !tokenizer.hasMoreTokens()) { try { tokenizer = new java.util.StringTokenizer(reader.readLine()); } catch (Exception e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } private static double nd() { return Double.parseDouble(next()); } private static long nl() { return Long.parseLong(next()); } private static int[] na(int n) { int[] a = new int[n]; for (int i = 0; i < n; i++) a[i] = ni(); return a; } private static char[] ns() { return next().toCharArray(); } private static long[] nal(int n) { long[] a = new long[n]; for (int i = 0; i < n; i++) a[i] = nl(); return a; } private static int[][] ntable(int n, int m) { int[][] table = new int[n][m]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { table[i][j] = ni(); } } return table; } private static int[][] nlist(int n, int m) { int[][] table = new int[m][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { table[j][i] = ni(); } } return table; } private static int ni() { return Integer.parseInt(next()); } private static void tr(Object... o) { if (is != System.in) System.out.println(java.util.Arrays.deepToString(o)); } }