#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int W, H, n;

int compress(vector<int> &x1, vector<int> &x2, int w) {
	vector<int> xs;

	rep(i, n) {
		for(int d = -1; d <= 1; d++) {
			int tx1 = x1[i] + d, tx2 = x2[i] + d;
			if(1 <= tx1 && tx1 < w) xs.push_back(tx1);
			if(1 <= tx2 && tx2 < w) xs.push_back(tx2);
		}
	}

	xs.push_back(0);
	xs.push_back(w-1);

	sort(xs.begin(), xs.end());
	xs.erase(unique(xs.begin(),xs.end()),xs.end());

	rep(i, n) {
		x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin();
		x2[i] = find(xs.begin(), xs.end(), x2[i]) - xs.begin();
	}

	return xs.size();
}

bool used[1000 * 6 + 5][1000 * 6 + 5];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

bool can(int y,int x) {
	if(0 <= y && y < H && 0 <= x && x < W) return true;
	return false;
}

int main() {

	while(cin >> W >> H) {
		if(W == 0 && H == 0) break;
		cin >> n;

		vector<int> x1(n), x2(n), y1(n), y2(n);
		rep(i, n) {
			cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
		}

		W = compress(x1, x2, W);
		H = compress(y1, y2, H);

		memset(used, 0, sizeof(used));
		rep(i, n) {
			REP(y, y1[i], y2[i]) {
				REP(x, x1[i], x2[i]) {
					used[y][x] = true;
				}
			}
		}

		int ans = 0;
		rep(i, H) {
			rep(j, W) {
				if(used[i][j]) continue;
				ans++;

				queue<P> que;
				que.push(mp(i, j));
				used[i][j] = true;

				while(que.size()) {
					P p = que.front();
					que.pop();

					rep(k, 4) {
						int ny = p.first + dy[k];
						int nx = p.second + dx[k];

						if(can(ny, nx) && !used[ny][nx]) {
							used[ny][nx] = true;
							que.push(mp(ny, nx));
						}
					}
				}
			}
		}

		cout << ans << endl;
	}

	return 0;
}