OI XVII - owc

// https://szkopul.edu.pl/problemset/problem/ZJVIyol5_xl_W3I8dFikC_5F/site/?key=statement

#include <bits/stdc++.h>

// #define GARY_DBG
#define GARY_LIB

constexpr int N = 602;

#define ar std::array

typedef std::vector<std::vector<int>> _kra;

struct Point {
    int x, y;
};

int cross(const Point& a, const Point& b, const Point& c) {
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

int trojkat[N][N];
int S[N][N];
bool zla_przekatna[N][N];
int dp[N][N];

bool czy_punkt_w_trojkacie(const Point& a, const Point& b, const Point& c, const Point& o) {
    return (cross(a, b, o) > 0) && (cross(b, c, o) > 0) && (cross(c, a, o) > 0);
}
int n, k, m;

void safe_increment(int& y) {
    if (++y >= n) y = 0;
}
int safe_plus_1(const int y) {
    if ((y + 1) >= n) return 0;
    return y + 1;
}
int safe_add(int a, int b) {
    if ((a + b) >= n) return a + b - n;
    return a + b;
}

void solve() {
    std::cin >> n >> k >> m;

    std::vector<Point> points(n);
    for (auto& [x, y] : points) {
        std::cin >> x >> y;
    }
    std::reverse(points.begin(), points.end());

    std::vector<Point> owce(k);
    for (auto& [x, y] : owce) {
        std::cin >> x >> y;
    }

    for (const auto& o : owce) {
        int y = 1;
        for (int x = 0; x < n; x++) {
            while (cross(points[x], points[y], o) > 0) {
                y = safe_plus_1(y);
            }

            if (cross(points[x], points[y], o) == 0) {
                zla_przekatna[x][y] = zla_przekatna[y][x] = true;
            }

            trojkat[x][y] ^= 1;
        }
    }

    for (int d = 2; d < n; d++) {
        for (int x = 0; x < n; x++) {
            int prev = safe_add(x, d - 1);
            int y = safe_plus_1(prev);

            S[x][y] = S[x][prev] ^ trojkat[x][y];
        }
    }

    for (int i = 0; i < n; i++) {
        dp[i][safe_plus_1(i)] = 1;
    }

    for (int d = 2; d < n; d++) {
        for (int i = 0; i < n; i++) {
            int j = safe_add(i, d);

            if (zla_przekatna[i][j]) {
                continue;
            }

            for (int s = 1; s < d; s++) {
                int l = safe_add(i, s);

                if ((s > 1 && zla_przekatna[i][l]) || (d - s > 1 && zla_przekatna[l][j])) {
                    continue;
                }

                int cnt = S[i][l] ^ S[l][j] ^ S[j][i];
                if (cnt == 0) {
                    dp[i][j] = (dp[i][j] + dp[i][l] * dp[l][j]) % m;
                }
            }
        }
    }

    int ans = dp[0][n - 1];

    std::cout << ans << '\n';
}

int32_t main() {
#ifndef GARY_DBG
    std::ios_base::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
#endif

    int t = 1;
    // std::cin >> t;

    for (; t > 0; t--) {
        solve();
    }

    return 0;
}