#include <bits/stdc++.h>
using namespace std;
#define forsn(i, s, n) for (int i = int(s); i < int(n); i++)
#define forn(i, n) forsn(i, 0, n)
#define dforsn(i, s, n) for (int i = int(n) - 1; i >= int(s); i--)
#define dforn(i, n) dforsn(i, 0, n)
#define qforn(i, n) for (i = 0; i < n; i++)
using vi = vector<int>;
using ii = pair<int, int>;
using vii = vector<ii>;
using ll = long long;
using ld = long double;
using vll = vector<ll>;
using vb = vector<bool>;
using pll = pair<ll, ll>;
#define sz(x) int(x.size())
#define all(x) begin(x), end(x)
#define pb push_back
#define eb emplace_back
#define fst first
#define snd second
const int ADD = 1;
const int ERASE = 3;
const int QUERY = 2;
struct FTree {
int n;
vll ft;
FTree(int _n) : n(_n + 9), ft(n, 0) {}
void update(int p, ll v) {
for (++p; p < n; p += p & -p) ft[p] += v;
}
ll get(int p) {
ll s = 0;
for (; p > 0; p -= p & -p) s += ft[p];
return s;
}
};
struct DSU {
vi p;
int c;
DSU(int n = 0) : p(n, -1), c(n) {}
int find(int x) {
if (p[x] < 0) return x;
return p[x] = find(p[x]);
}
void unite(int x, int y) {
x = find(x), y = find(y);
if (x == y) return;
if (p[x] > p[y]) swap(x, y);
p[x] += p[y], p[y] = x, c--;
}
};
using Event = tuple<int, int, int, int, int>;
struct Node;
DSU dsu;
using NodePtr = Node*;
struct Node {
int x;
int u;
int lazy;
int priority;
NodePtr left, right;
Node(int val, int id) {
x = val;
u = id;
lazy = -1;
priority = rand();
left = right = nullptr;
}
void addLazy(int id) {
if (lazy == -1) lazy = id;
dsu.unite(lazy, id);
lazy = id;
}
void applyLazy() {
if (lazy == -1) return;
if (left != nullptr) left->addLazy(lazy);
if (right != nullptr) right->addLazy(lazy);
dsu.unite(u, lazy);
lazy = -1;
}
};
pair<NodePtr, NodePtr> split(NodePtr u, int k) {
if (u == nullptr) return make_pair(nullptr, nullptr);
u->applyLazy();
if (u->x < k) {
auto [left, right] = split(u->right, k);
u->right = left;
return make_pair(u, right);
} else {
auto [left, right] = split(u->left, k);
u->left = right;
return make_pair(left, u);
}
}
NodePtr merge(NodePtr left, NodePtr right) {
if (right == nullptr) return left;
if (left == nullptr) return right;
if (left->priority > right->priority) {
left->applyLazy();
left->right = merge(left->right, right);
return left;
} else {
right->applyLazy();
right->left = merge(left, right->left);
return right;
}
}
NodePtr insert(NodePtr root, int x, int i) {
auto [left, right] = split(root, x);
return merge(merge(left, new Node(x, i)), right);
}
NodePtr erase(NodePtr root, int x) {
auto [left, aux] = split(root, x);
auto [middle, right] = split(aux, x + 1);
middle->applyLazy();
return merge(left, right);
}
NodePtr update(NodePtr root, int x1, int x2, int idx) {
auto [left, aux] = split(root, x1);
auto [middle, right] = split(aux, x2 + 1);
if (middle != nullptr) middle->addLazy(idx);
return merge(merge(left, middle), right);
}
void dfs(NodePtr root) {
if (root == nullptr) return;
root->applyLazy();
dfs(root->left);
dfs(root->right);
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int w, h, n;
cin >> w >> h >> n;
vector<tuple<int, int, int, int>> v = {
{0, 0, w, 0},
{w, 0, w, h},
{w, h, 0, h},
{0, h, 0, 0}
};
forn(i, n) {
int a, b, c, d;
cin >> a >> b >> c >> d;
v.eb(a, b, c, d);
}
vector<Event> events;
vii pos;
for (int i = 0; auto [a, b, c, d] : v) {
pos.eb(b, i), pos.eb(d, i);
if (a == c) {
if (b > d) swap(b, d);
events.eb(a, QUERY, b, d, i);
} else {
if (a > c) swap(a, c);
assert(b == d);
events.eb(a, ADD, b, d, i);
events.eb(c, ERASE, b, d, i);
}
i++;
}
sort(all(events));
sort(all(pos));
pos.erase(unique(all(pos)), end(pos));
ll ret = -sz(v);
dsu = DSU(sz(v));
NodePtr root = nullptr;
int cnt = 0;
for (FTree ft(sz(pos)); auto [_, t, x1, x2, i] : events) {
if (t == ADD) {
x1 = int(lower_bound(all(pos), make_pair(x1, i)) - begin(pos));
ft.update(x1, +1);
root = insert(root, x1, i);
} else if (t == ERASE) {
x1 = int(lower_bound(all(pos), make_pair(x1, i)) - begin(pos));
ft.update(x1, -1);
root = erase(root, x1);
} else {
x1 = int(lower_bound(all(pos), make_pair(x1, 0)) - begin(pos));
x2 = int(lower_bound(all(pos), make_pair(x2 + 1, 0)) - begin(pos) - 1);
root = update(root, x1, x2, i);
ll curr = ft.get(x2 + 1) - ft.get(x1);
ret += curr;
}
}
dfs(root);
int C = dsu.c;
cout << ret + C << "\n";
return 0;
}