Problem:
ペンキの色
問題
情報オリンピックの宣伝のために,長方形のベニヤ板にペンキを塗り看板を制作したい.ベニヤ板には色を塗りたくないところにあらかじめ何枚かの長方形のマスキングテープが貼られている.そこでマスキングテープで区切られた領域ごとに別々の色を使いペンキを塗ることにした.例えば,図 5-1 の場合は 5 色のペンキを使う.
入力としてマスキングテープを貼る位置が与えられた時,使うペンキの色の数を求めるプログラムを作成せよ.ただし,ベニヤ板全体がマスキングテープで覆われることはなく,全てのマスキングテープの辺はベニヤ板のいずれかの辺に平行である.
入力
入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．
1 行目にはベニヤ板の幅 w (1  ≤  w  ≤  1000000 となる整数) と高さ h (1  ≤   h ≤ 1000000 となる整数) がこの順に空白区切りで書かれている.
2 行目にはマスキングテープの数 n (1 ≤ n ≤ 1000 となる整数) が書かれている.
続く 3 行目以降の 2 + i 行目 (1 ≤ i ≤ n) には,i 番目に貼るマスキングテープの左下の座標 (x
1
, y
1
) と,右上の座標 (x
2
, y
2
) が x
1
, y
1
, x
2
, y
2
(0 ≤ x
1
< x
2
≤  w, 0 ≤ y
1
< y
2
≤  h となる整数) の順に空白区切りで書かれている.
ただし,ベニヤ板の左下の角の座標は (0, 0) で右上の角の座標は (w, h) である.  採点用データのうち, 配点の 30% 分は w ≤ 100, h ≤ 100, n ≤ 100 を満たす.
h, w がともに 0 のとき入力の終了を示す. データセットの数は 20 を超えない．
出力
データセットごとに使うペンキの色数を１行に出力する.
入出力例
次の例は図 5-1 の場合である.
入力例
15 6
10
1 4 5 6
2 1 4 5
1 0 5 1
6 1 7 5
7 5 9 6
7 0 9 2
9 1 10 5
11 0 14 1
12 1 13 5
11 5 14 6
0 0
出力例
5
上記問題文と自動審判に使われるデータは、
情報オリンピック日本委員会
が作成し公開している問題文と採点用テストデータです。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

// 整数ペアを表すエイリアス
using pii = pair<int,int>;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    while(true){
        int W, H;
        cin >> W >> H;
        if(!W) break;  // W==0 で終了

        int N;
        cin >> N;

        // 入力される長方形のリスト
        vector<array<int,4>> rects(N);
        // 圧縮用の x, y 座標集合
        vector<int> xs, ys;

        for(int i = 0; i < N; i++){
            int x1,y1,x2,y2;
            cin >> x1 >> y1 >> x2 >> y2;
            rects[i] = {x1,y1,x2,y2};

            // ±1 マージンも含めて圧縮座標に登録
            for(auto dx : {-1,0,1}){
                int tx1 = x1 + dx, tx2 = x2 + dx;
                if(0 <= tx1 && tx1 < W) xs.push_back(tx1);
                if(0 <= tx2 && tx2 < W) xs.push_back(tx2);
            }
            for(auto dy : {-1,0,1}){
                int ty1 = y1 + dy, ty2 = y2 + dy;
                if(0 <= ty1 && ty1 < H) ys.push_back(ty1);
                if(0 <= ty2 && ty2 < H) ys.push_back(ty2);
            }
        }

        // 重複を取り除いてソート
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
        sort(ys.begin(), ys.end());
        ys.erase(unique(ys.begin(), ys.end()), ys.end());

        // 座標を圧縮インデックスに置き換え
        for(auto& r : rects){
            r[0] = int(lower_bound(xs.begin(), xs.end(), r[0]) - xs.begin());
            r[2] = int(lower_bound(xs.begin(), xs.end(), r[2]) - xs.begin());
            r[1] = int(lower_bound(ys.begin(), ys.end(), r[1]) - ys.begin());
            r[3] = int(lower_bound(ys.begin(), ys.end(), r[3]) - ys.begin());
        }

        // 圧縮後のグリッドサイズ
        int w = xs.size(), h = ys.size();
        // 塗られたマスを true にするフィールド
        vector<vector<bool>> field(w, vector<bool>(h, false));

        // 長方形ごとに内部を塗りつぶし
        for(auto [x1,y1,x2,y2] : rects){
            for(int x = x1; x < x2; x++){
                for(int y = y1; y < y2; y++){
                    field[x][y] = true;
                }
            }
        }

        // 未塗りマスの連結領域数をカウント
        int regions = 0;
        array<int,4> dir{0,1,0,-1};  // dx,dy を交互に参照

        for(int sx = 0; sx < w; sx++){
            for(int sy = 0; sy < h; sy++){
                if(!field[sx][sy]){
                    // 新しい領域を発見
                    regions++;
                    // BFS で領域を塗りつぶし
                    queue<pii> q;
                    field[sx][sy] = true;
                    q.emplace(sx, sy);
                    while(!q.empty()){
                        auto [x,y] = q.front();
                        q.pop();
                        // 4 方向に拡張
                        for(int k = 0; k < 4; k++){
                            int nx = x + dir[k];
                            int ny = y + dir[(k+1)%4];
                            if(nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
                            if(field[nx][ny]) continue;
                            field[nx][ny] = true;
                            q.emplace(nx, ny);
                        }
                    }
                }
            }
        }

        // 領域数を出力
        cout << regions << "\n";
    }

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3968
final_rank: 2

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

int x1[1010], x2[1010], y1[1010], y2[1010], N, W, H;
bool fid[10010][10010];
int compress(int x1[], int x2[], int w) {
  vector<int> xs;
  xs.push_back(0);
  xs.push_back(w);
  for (int i = 1; i <= N; ++i)
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w) xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w) xs.push_back(tx2);
    }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  for (int i = 1; i <= N; ++i) {
    x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin() + 1;
    x2[i] = find(xs.begin(), xs.end(), x2[i]) - xs.begin() + 1;
  }
  return xs.size() - 1;
}
int bfs() {
  int ans = 0;
  const int flag[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
  memset(fid, 0, sizeof(fid));
  for (int i = 1; i <= N; ++i)
    for (int y = y1[i]; y < y2[i]; ++y)
      for (int x = x1[i]; x < x2[i]; ++x) fid[x][y] = true;
  for (int i = 1; i <= W; ++i)
    for (int j = 1; j <= H; ++j) {
      if (fid[i][j]) continue;
      ++ans;
      queue<pair<int, int>> que;
      que.push(make_pair(i, j));
      while (!que.empty()) {
        int sx = que.front().first, sy = que.front().second;
        que.pop();
        for (int k = 0; k < 4; ++k) {
          int tx = sx + flag[k][0], ty = sy + flag[k][1];
          if (tx < 1 || tx > W || ty < 1 || ty > H || fid[tx][ty]) continue;
          fid[tx][ty] = true;
          que.push(make_pair(tx, ty));
        }
      }
    }
  return ans;
}
int main() {
  //freopen("aizu0531.in", "r", stdin);
  while (scanf("%d %d", &W, &H) == 2 && W + H) {
    scanf("%d", &N);
    for (int i = 1; i <= N; ++i)
      scanf("%d %d %d %d", &x1[i], &y1[i], &x2[i], &y2[i]);
    W = compress(x1, x2, W);
    H = compress(y1, y2, H);
    printf("%d\n", bfs());
  }
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 100804
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
random_device seed_gen;mt19937 rnd(seed_gen());

using ll = long long;using ull = unsigned long long;
using vi = vector<int>;using vvi = vector<vi>;using vvvi = vector<vvi>;
using vl = vector<ll>;using vvl = vector<vl>;using vvvl = vector<vvl>;
template<typename T>inline bool chmax(T& a, T b) { return ((a < b) ? (a = b, true) : (false)); }
template<typename T>inline bool chmin(T& a, T b) { return ((a > b) ? (a = b, true) : (false)); }
bool eq(double a, double b) { return abs(a - b) < 0.0000001; }
const int di4[4] = { 0,-1,0,1 },dj4[4] = { -1,0,1,0 };//LRUD
const int di8[8] = { 0,0,1,1,1,-1,-1,-1 },dj8[8] = { 1,-1,0,-1,1,0,-1,1 };

#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define Rrep(i,n) for(int i=n-1;i>=0;i--)
#define Rrep1(i,n) for(int i=n;i>0;i--)
#define all(a) a.begin(),a.end()
#define yesno(ans) cout<<((ans)?"Yes\n":"No\n")
#define YESNO(ans) cout<<((ans)?"YES\n":"NO\n")
#define INF ((ll)2e18)
#define IINF ((int)(1e9+5e8))
const double PI = 3.1415926535897932384626;
#define eb emplace_back
#define pb push_back


int solve();
int main(){
    int T=1;
    //cin>>T;
    while (1){
        if(solve())break;
    }
    return 0;
}

int W,H;
void dfs(int i,int j,vvi&memo){
    memo[i][j]=1;
    rep(d,4){
        int ni=i+di4[d];
        int nj=j+dj4[d];
        if(ni<0||ni>=H||nj<0||nj>=W)continue;
        if(memo[ni][nj]==0)dfs(ni,nj,memo);
    }
}

int solve() {
    cin>>W>>H;
    if(W==0)return 1;
    int N;cin>>N;
    vi X1(N),Y1(N),X2(N),Y2(N);
    vi X,Y;
    rep(i,N){
        cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i];
        for(int d=-1;d<=1;d++){
            if(X1[i]+d>=0&&X1[i]+d<W)X.pb(X1[i]+d);
            if(X1[i]+d>=0&&X2[i]+d<W)X.pb(X2[i]+d);
            if(Y1[i]+d>=0&&Y1[i]+d<H)Y.pb(Y1[i]+d);
            if(Y2[i]+d>=0&&Y2[i]+d<H)Y.pb(Y2[i]+d);
        }
    }
    sort(all(X));
    sort(all(Y));
    X.erase(unique(all(X)),X.end());
    Y.erase(unique(all(Y)),Y.end());
    H=Y.size();
    W=X.size();
    vvi memo(H+1,vi(W+1));
    rep(i,N){
        X1[i]=lower_bound(all(X),X1[i])-X.begin();
        X2[i]=lower_bound(all(X),X2[i])-X.begin();
        Y1[i]=lower_bound(all(Y),Y1[i])-Y.begin();
        Y2[i]=lower_bound(all(Y),Y2[i])-Y.begin();
        memo[Y1[i]][X1[i]]++;
        memo[Y1[i]][X2[i]]--;
        memo[Y2[i]][X1[i]]--;
        memo[Y2[i]][X2[i]]++;
    }
    rep(i,H+1)rep(j,W)memo[i][j+1]+=memo[i][j];
    rep(i,H)rep(j,W+1)memo[i+1][j]+=memo[i][j];

    int ans=0;
    rep(i,H)rep(j,W)if(memo[i][j]==0){
        ans++;
        dfs(i,j,memo);
    }
    cout<<ans<<"\n";
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 34228
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
using namespace std;

const int MAX_N = 1000;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
int w, h, n, x1, x2, y1, y2;
int xs[MAX_N * 2], ys[MAX_N * 2];
bool used[MAX_N * 6][MAX_N * 6];

int main() {
    while (cin >> w >> h) {
        if (w == 0 && h == 0)
            break;
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> x1 >> y1 >> x2 >> y2;
            xs[i * 2] = x1 * 2; xs[i * 2 + 1] = x2 * 2;
            ys[i * 2] = y1 * 2; ys[i * 2 + 1] = y2 * 2;
        }
        vector<int> xc, yc;
        for (int i = 0; i < n * 2; i++) {
            for (int d = -1; d <= 1; d++) {
                int tx = xs[i] + d, ty = ys[i] + d;
                if (tx >= 0 && tx <= w * 2)
                    xc.push_back(tx);
                if (ty >= 0 && ty <= h * 2)
                    yc.push_back(ty);
            }
        }
        sort(xc.begin(), xc.end());
        sort(yc.begin(), yc.end());
        xc.erase(unique(xc.begin(), xc.end()), xc.end());
        yc.erase(unique(yc.begin(), yc.end()), yc.end());
        int wc = xc.size(), hc = yc.size();
        fill((bool*)used, (bool*)(used + MAX_N * 6), false);
        for (int i = 0; i < n; i++) {
            x1 = lower_bound(xc.begin(), xc.end(), xs[i * 2]) - xc.begin();
            x2 = lower_bound(xc.begin(), xc.end(), xs[i * 2 + 1]) - xc.begin();
            y1 = lower_bound(yc.begin(), yc.end(), ys[i * 2]) - yc.begin();
            y2 = lower_bound(yc.begin(), yc.end(), ys[i * 2 + 1]) - yc.begin();
            for (int j = x1; j <= x2; j++) {
                for (int k = y1; k <= y2; k++)
                    used[j][k] = true;
            }
        }
        int ans = 0;
        queue<pair<int, int>> que;
        for (int i = 0; i < wc; i++) {
            for (int j = 0; j < hc; j++) {
                if (!used[i][j]) {
                    ans++;
                    que.push(make_pair(i, j));
                    used[i][j] = true;
                    while (!que.empty()) {
                        for (int d = 0; d < 4; d++) {
                            int nx = que.front().first + dx[d], ny = que.front().second + dy[d];
                            if (nx >= 0 && nx < wc && ny >= 0 && ny < hc && !used[nx][ny]) {
                                que.push(make_pair(nx, ny));
                                used[nx][ny] = true;
                            }
                        }
                        que.pop();
                    }
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 38552
final_rank: 16

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define y1 hogwhoasjfd
#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> p) {
  os << "(" << p.fst << ", " << p.scd << ")";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> v) {
  rep(i, v.size()) {
    if (i)
      os << ", ";
    os << v[i];
  }
  return os;
}
template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
vector<int> x1(1005), x2(1005); // Use vectors instead of fixed-size arrays
vector<int> y1(1005), y2(1005);
bool fld[1005 * 6 + 2][1005 * 6 + 2];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int compress(vector<int> &x1, vector<int> &x2, int w) { // Use vector references
  vi xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.PB(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.PB(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(xs), x1[i]) - begin(xs);
    x2[i] = lower_bound(all(xs), x2[i]) - begin(xs);
  }
  return xs.size();
}
int main() {
  omajinai;
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pii> q;
      q.push(pii(y, x));
      while (q.size()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.fst + dy[i], nx = p.scd + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.push(pii(ny, nx));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 38792
final_rank: 8

code_snippet: #include <algorithm>
#include <set>
#include <queue>
#include <iostream>
using namespace std;

#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)
typedef pair<int, int> pii;

int w, h, n;
int x1[1005], x2[1005], y1[1005], y2[1005];
set<pii> fld;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};

int compress(int *x1, 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 (0 <= tx1 && tx1 <= w)
        xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.push_back(tx2);
    }
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  rep(i, n) {
    x1[i] = lower_bound(xs.begin(), xs.end(), x1[i]) - xs.begin();
    x2[i] = lower_bound(xs.begin(), xs.end(), x2[i]) - xs.begin();
  }
  return xs.size();
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  while (cin >> w >> h, w) {
    cin >> n;
    fld.clear();
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld.insert(make_pair(y, x));
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld.find(make_pair(y, x)) != fld.end())
        continue;
      ans++;
      queue<pii> q;
      q.push(make_pair(y, x));
      while (q.size()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.first + dy[i], nx = p.second + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld.find(make_pair(ny, nx)) != fld.end())
            continue;
          fld.insert(make_pair(ny, nx));
          q.push(make_pair(ny, nx));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 1690
memory_kb: 87552
final_rank: 20

code_snippet: #include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
#define y1 hogwhoasjfd
#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai                                                               \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;
using stpii = stack<pii>;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> p) {
  os << "(" << p.fst << ", " << p.scd << ")";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> v) {
  rep(i, v.size()) {
    if (i)
      os << ", ";
    os << v[i];
  }
  return os;
}
template <typename T> T &max(T &a, T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> T &min(T &a, T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int compress(int *x1, int *x2, int w) {
  vi xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.PB(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.PB(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(xs), x1[i]) - begin(xs);
    x2[i] = lower_bound(all(xs), x2[i]) - begin(xs);
  }
  return xs.size();
}
int main() {
  omajinai;
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        memset(fld[y] + x1[i], 1, x2[i] - x1[i]); // use memset instead of inner loop
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      stpii s; // use stack instead of queue
      s.push(pii(y, x));
      while (s.size()) {
        pii p = s.top();
        s.pop();
        rep(i, 4) {
          int ny = p.fst + dy[i], nx = p.scd + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          s.push(pii(ny, nx));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 40920
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <queue>
#include <cstring>

using namespace std;

#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define all(a) a.begin(), a.end()

using vi = vector<int>;
using pii = pair<int, int>;

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

int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];

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

  vi vxs(all(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(vxs), x1[i]) - vxs.begin();
    x2[i] = lower_bound(all(vxs), x2[i]) - vxs.begin();
  }
  
  return vxs.size();
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);

    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pii> q;
      q.push(pii(y, x));
      fld[y][x] = true;
      while (!q.empty()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.first + dy[i], nx = p.second + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          q.push(pii(ny, nx));
          fld[ny][nx] = true;
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 38900
final_rank: 9

code_snippet: #include <algorithm>
#include <vector>
#include <unordered_map>
#include <iostream>
#include <cstring>
using namespace std;

#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define all(a) a.begin(), a.end()
using pii = pair<int, int>;

int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];

int compress(int *x1, 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 (0 <= tx1 && tx1 <= w)
        xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.push_back(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  
  unordered_map<int, int> xs_map;
  int idx = 0;
  for(int x : xs)
    xs_map[x] = idx++;

  rep(i, n) {
    x1[i] = xs_map[x1[i]];
    x2[i] = xs_map[x2[i]];
  }
  return xs.size();
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    vector<pii> q;
    int head = 0; // Our manual queue head index
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      q.push_back(pii(y, x));
      fld[y][x] = true;
      while (head < q.size()) {
        pii p = q[head++];
        int ny, nx;
        ny = p.first - 1, nx = p.second;
        if (ny >= 0 && !fld[ny][nx]) {
          q.push_back(pii(ny, nx));
          fld[ny][nx] = true;
        }
        ny = p.first, nx = p.second - 1;
        if (nx >= 0 && !fld[ny][nx]) {
          q.push_back(pii(ny, nx));
          fld[ny][nx] = true;
        }
        ny = p.first + 1, nx = p.second;
        if (ny < h - 1 && !fld[ny][nx]) {
          q.push_back(pii(ny, nx));
          fld[ny][nx] = true;
        }
        ny = p.first, nx = p.second + 1;
        if (nx < w - 1 && !fld[ny][nx]) {
          q.push_back(pii(ny, nx));
          fld[ny][nx] = true;
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 64176
final_rank: 18

code_snippet: #include <algorithm>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai ios::sync_with_stdio(false); cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
using vpii = vector<pii>;
constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int compress(int *x1, int *x2, int w) {
  vi xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.PB(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.PB(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(xs), x1[i]) - begin(xs);
    x2[i] = lower_bound(all(xs), x2[i]) - begin(xs);
  }
  return xs.size();
}
int main() {
  omajinai;
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pii> q;
      q.push(pii(y, x));
      while (q.size()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.fst + dy[i], nx = p.scd + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.push(pii(ny, nx));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 38720
final_rank: 13

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;

constexpr int inf = 1e9;
constexpr long long linf = 3e18;
constexpr double eps = 1e-9;
constexpr int dx[4] = {-1, 0, 1, 0};
constexpr int dy[4] = {0, -1, 0, 1};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int w, h, n;
  while (cin >> w >> h, w) {
    cin >> n;

    vector<int> x1(n), x2(n), y1(n), y2(n);
    vector<vector<bool>> fld(h, vector<bool>(w, false));

    for (int i = 0; i < n; ++i) {
      cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
    }

    for (int i = 0; i < n; ++i) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }

    int ans = 0;
    for (int y = 0; y < h - 1; ++y) {
      for (int x = 0; x < w - 1; ++x) {
        if (fld[y][x])
          continue;
        ans++;
        queue<pair<int, int>> q;
        q.push(make_pair(y, x));
        while (!q.empty()) {
          pair<int, int> p = q.front();
          q.pop();
          for (int i = 0; i < 4; ++i) {
            int ny = p.first + dy[i], nx = p.second + dx[i];
            if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
              continue;
            fld[ny][nx] = true;
            q.push(make_pair(ny, nx));
          }
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 160
memory_kb: 4580
final_rank: 5

code_snippet: #include <cstdio>
#include <cstring>
#include <algorithm>
#include <deque>
#include <vector>
using namespace std;
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define all(a) a.begin(), a.end()
#define PB push_back
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int compress(int *x1, int *x2, int w) {
  vi xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.PB(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.PB(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(xs), x1[i]) - begin(xs);
    x2[i] = lower_bound(all(xs), x2[i]) - begin(xs);
  }
  return xs.size();
}
int main() {
  while (scanf("%d%d", &w, &h), w) {
    scanf("%d", &n);
    memset(fld, 0, sizeof fld);
    rep(i, n) { scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]); }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      deque<pii> q;
      q.push_back(pii(y, x));
      while (!q.empty()) {
        pii p = q.front();
        q.pop_front();
        rep(i, 4) {
          int ny = p.first + dy[i], nx = p.second + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.push_back(pii(ny, nx));
        }
      }
    }
    printf("%d\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 38476
final_rank: 7

code_snippet: #include <algorithm>
#include <array>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;
#define y1 hogwhoasjfd
#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai ios::sync_with_stdio(false); cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;

constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
array<int, 1005> x1, x2;
array<int, 1005> y1, y2;
bool fld[1005 * 6 + 2][1005 * 6 + 2];
array<int, 4> dx = {-1, 0, 1, 0};
array<int, 4> dy = {0, -1, 0, 1};

int compress(array<int, 1005> &x1, array<int, 1005> &x2, int w) {
  unordered_set<int> xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.insert(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.insert(tx2);
    }
  }
  vi xs_sorted(xs.begin(), xs.end());
  sort(xs_sorted.begin(), xs_sorted.end());
  rep(i, n) {
    x1[i] = lower_bound(xs_sorted.begin(), xs_sorted.end(), x1[i]) - xs_sorted.begin();
    x2[i] = lower_bound(xs_sorted.begin(), xs_sorted.end(), x2[i]) - xs_sorted.begin();
  }
  return xs.size();
}

int main() {
  omajinai;
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pii> q;
      q.emplace(y, x);
      while (!q.empty()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.fst + dy[i], nx = p.scd + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.emplace(ny, nx);
        }
      }
    }
    cout << ans << '\n';
  }
}
accuracy: 1
time_ms: 40
memory_kb: 38960
final_rank: 14

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define omajinai ios::sync_with_stdio(false); cin.tie(0)
#define rep(i, x) for (int i = 0; i < (int)(x); ++i)
#define rep1(i, x) for (int i = 1; i <= (int)(x); ++i)
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vpii = vector<pii>;
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.fst << ", " << p.scd << ")";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  rep(i, v.size()) {
    if (i)
      os << ", ";
    os << v[i];
  }
  return os;
}
template <typename T> const T &max(const T &a, const T &b) {
  if (a >= b)
    return a;
  return b;
}
template <typename T> const T &min(const T &a, const T &b) {
  if (a < b)
    return a;
  return b;
}
template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
constexpr int inf = 1e9;
constexpr ll linf = 3e18;
constexpr double eps = 1e-9;
int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[6010][6010];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int compress(int *x1, int *x2, int w) {
  vi xs;
  rep(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.PB(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.PB(tx2);
    }
  }
  sort(all(xs));
  xs.erase(unique(all(xs)), end(xs));
  rep(i, n) {
    x1[i] = lower_bound(all(xs), x1[i]) - begin(xs);
    x2[i] = lower_bound(all(xs), x2[i]) - begin(xs);
  }
  return xs.size();
}
int main() {
  omajinai;
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    rep(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    rep(i, n) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    rep(y, h - 1) rep(x, w - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pii> q;
      q.push(pii(y, x));
      while (q.size()) {
        pii p = q.front();
        q.pop();
        rep(i, 4) {
          int ny = p.fst + dy[i], nx = p.scd + dx[i];
          if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.push(pii(ny, nx));
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 40
memory_kb: 38648
final_rank: 12

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
using pii = pair<int, int>;
constexpr int dx[4] = {-1, 0, 1, 0};
constexpr int dy[4] = {0, -1, 0, 1};
int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];

int compress(int *x1, int *x2, int w) {
  vector<int> xs;
  for (int i = 0; i < n; ++i) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.push_back(tx2);
    }
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  for (int i = 0; i < n; ++i) {
    x1[i] = lower_bound(xs.begin(), xs.end(), x1[i]) - xs.begin();
    x2[i] = lower_bound(xs.begin(), xs.end(), x2[i]) - xs.begin();
  }
  return xs.size();
}

int main() {
  ios::sync_with_stdio(false);                                                 
  cin.tie(0);
  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    for (int i = 0; i < n; ++i) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    for (int i = 0; i < n; ++i) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    for (int y = 0; y < h - 1; ++y) {
      for (int x = 0; x < w - 1; ++x) {
        if (fld[y][x])
          continue;
        ans++;
        queue<pii> q;
        q.emplace(y, x);
        while (q.size()) {
          pii p = q.front();
          q.pop();
          for (int i = 0; i < 4; ++i) {
            int ny = p.first + dy[i], nx = p.second + dx[i];
            if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
              continue;
            fld[ny][nx] = true;
            q.emplace(ny, nx);
          }
        }
      }
    }
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 38944
final_rank: 10

code_snippet: #include <algorithm>
#include <iostream>
#include <queue>
#include <vector>

constexpr int inf = 1e9;

int w, h;
int n;
std::vector<int> x1, x2, y1, y2;
std::vector<std::vector<bool>> fld;
std::vector<int> dx = {-1, 0, 1, 0};
std::vector<int> dy = {0, -1, 0, 1};

int compress(std::vector<int>& x1, std::vector<int>& x2, int w) {
  std::vector<int> xs;
  for (int i = 0; i < n; ++i) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w) xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w) xs.push_back(tx2);
    }
  }
  std::sort(xs.begin(), xs.end());
  xs.erase(std::unique(xs.begin(), xs.end()), xs.end());
  for (int i = 0; i < n; ++i) {
    x1[i] = std::lower_bound(xs.begin(), xs.end(), x1[i]) - xs.begin();
    x2[i] = std::lower_bound(xs.begin(), xs.end(), x2[i]) - xs.begin();
  }
  return xs.size();
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  while (std::cin >> w >> h, w) {
    std::cin >> n;

    x1.resize(n);
    x2.resize(n);
    y1.resize(n);
    y2.resize(n);

    for (int i = 0; i < n; ++i) {
      std::cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
    }

    w = compress(x1, x2, w);
    h = compress(y1, y2, h);

    fld.assign(h, std::vector<bool>(w, false));

    for (int i = 0; i < n; ++i) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }

    int ans = 0;
    for (int y = 0; y < h - 1; ++y) {
      for (int x = 0; x < w - 1; ++x) {
        if (fld[y][x]) continue;
        ++ans;
        std::deque<std::pair<int, int>> q;
        q.push_back(std::make_pair(y, x));
        while (!q.empty()) {
          std::pair<int, int> p = q.front();
          q.pop_front();
          for (int i = 0; i < 4; ++i) {
            int ny = p.first + dy[i], nx = p.second + dx[i];
            if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
              continue;
            fld[ny][nx] = true;
            q.push_back(std::make_pair(ny, nx));
          }
        }
      }
    }

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

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3848
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

int w, h;
int n;
int x1[1005], x2[1005];
int y1[1005], y2[1005];
bool fld[1005 * 6 + 2][1005 * 6 + 2];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};

int compress(int *x1, int *x2, int w) {
  vector<int> xs;
  for (int i = 0; i < n; ++i) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.push_back(tx2);
    }
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  for (int i = 0; i < n; ++i) {
    int val = lower_bound(xs.begin(), xs.end(), x1[i]) - xs.begin();
    x1[i] = val;
    val = lower_bound(xs.begin(), xs.end(), x2[i]) - xs.begin();
    x2[i] = val;
  }
  return xs.size();
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  while (cin >> w >> h, w) {
    cin >> n;
    memset(fld, 0, sizeof fld);
    for (int i = 0; i < n; ++i) {
      cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
    }
    w = compress(x1, x2, w);
    h = compress(y1, y2, h);
    for (int i = 0; i < n; ++i) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    for (int y = 0; y < h - 1; ++y) {
      for (int x = 0; x < w - 1; ++x) {
        if (fld[y][x])
          continue;
        ans++;
        queue<pair<int, int>> q;
        q.push({y, x});
        while (!q.empty()) {
          pair<int, int> p = q.front();
          q.pop();
          for (int i = 0; i < 4; ++i) {
            int ny = p.first + dy[i], nx = p.second + dx[i];
            if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
              continue;
            fld[ny][nx] = true;
            q.push({ny, nx});
          }
        }
      }
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 38956
final_rank: 11

code_snippet: #include <algorithm>
#include <iostream>
#include <queue>
#include <unordered_set>
#include <vector>

constexpr int inf = 1e9;

int w, h;
int n;
std::vector<int> x1, x2, y1, y2;
std::vector<std::vector<bool>> fld;
std::vector<int> dx = {-1, 0, 1, 0};
std::vector<int> dy = {0, -1, 0, 1};

int compress(std::vector<int>& x1, std::vector<int>& x2, int w) {
  std::unordered_set<int> xs;
  for (int i = 0; i < n; ++i) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.insert(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.insert(tx2);
    }
  }
  std::vector<int> sorted_xs(xs.begin(), xs.end());
  std::sort(sorted_xs.begin(), sorted_xs.end());
  for (int i = 0; i < n; ++i) {
    x1[i] = std::lower_bound(sorted_xs.begin(), sorted_xs.end(), x1[i]) - sorted_xs.begin();
    x2[i] = std::lower_bound(sorted_xs.begin(), sorted_xs.end(), x2[i]) - sorted_xs.begin();
  }
  return sorted_xs.size();
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  while (std::cin >> w >> h, w) {
    std::cin >> n;
    x1.resize(n);
    x2.resize(n);
    y1.resize(n);
    y2.resize(n);
    fld.assign(6 * w + 2, std::vector<bool>(6 * h + 2, false));

    for (int i = 0; i < n; ++i) {
      std::cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
    }

    w = compress(x1, x2, w);
    h = compress(y1, y2, h);

    for (int i = 0; i < n; ++i) {
      for (int y = y1[i]; y <= y2[i] - 1; ++y) {
        for (int x = x1[i]; x <= x2[i] - 1; ++x) {
          fld[y][x] = true;
        }
      }
    }

    int ans = 0;
    for (int y = 0; y < h - 1; ++y) {
      for (int x = 0; x < w - 1; ++x) {
        if (fld[y][x])
          continue;

        ans++;
        std::queue<std::pair<int, int>> q;
        q.emplace(y, x);

        while (!q.empty()) {
          std::pair<int, int> p = q.front();
          q.pop();

          for (int i = 0; i < 4; ++i) {
            int ny = p.first + dy[i], nx = p.second + dx[i];
            if (ny < 0 || ny >= h - 1 || nx < 0 || nx >= w - 1 || fld[ny][nx])
              continue;
            fld[ny][nx] = true;
            q.emplace(ny, nx);
          }
        }
      }
    }

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

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 48384
final_rank: 17

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> P;
int x[6007], y[6007], xLen, yLen, w, h, x_1[1007], x_2[1007], y_1[1007], y_2[1007], n, ans;
int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
bool field[6007][6007];
queue<P> que;
void input()
{
    ans = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%d%d%d%d", &x_1[i], &y_1[i], &x_2[i], &y_2[i]);
    }
}
void compress()
{
    xLen = 0;
    for (int i = 0; i < n; i++)
    {
        if (x_1[i] > 0)
        {
            x[xLen++] = x_1[i] - 1;
        }
        x[xLen++] = x_1[i];
        if (x_1[i] < w)
        {
            x[xLen++] = x_1[i] + 1;
        }
        if (x_2[i] > 0)
        {
            x[xLen++] = x_2[i] - 1;
        }
        x[xLen++] = x_2[i];
        if (x_2[i] < w)
        {
            x[xLen++] = x_2[i] + 1;
        }
    }
    yLen = 0;
    for (int i = 0; i < n; i++)
    {
        if (y_1[i] > 0)
        {
            y[yLen++] = y_1[i] - 1;
        }
        y[yLen++] = y_1[i];
        if (y_1[i] < h)
        {
            y[yLen++] = y_1[i] + 1;
        }
        if (y_2[i] > 0)
        {
            y[yLen++] = y_2[i] - 1;
        }
        y[yLen++] = y_2[i];
        if (y_2[i] < h)
        {
            y[yLen++] = y_2[i] + 1;
        }
    }
    sort(x, x + xLen);
    sort(y, y + yLen);
}
void distinctBy2Posinter()
{
    int tmpLen = 1;
    for (int i = 1; i < xLen; i++)
    {
        if (x[tmpLen - 1] != x[i])
        {
            x[tmpLen++] = x[i];
        }
    }
    xLen = tmpLen;
    tmpLen = 1;
    for (int i = 1; i < yLen; i++)
    {
        if (y[tmpLen - 1] != y[i])
        {
            y[tmpLen++] = y[i];
        }
    }
    yLen = tmpLen;
}
void handleX_1X_2Y_1Y_2()
{
    for (int i = 0; i < n; i++)
    {
        x_1[i] = lower_bound(x, x + xLen, x_1[i]) - x;
        x_2[i] = lower_bound(x, x + xLen, x_2[i]) - x;
        y_1[i] = lower_bound(y, y + yLen, y_1[i]) - y;
        y_2[i] = lower_bound(y, y + yLen, y_2[i]) - y;
    }
    w = xLen - 1;
    h = yLen - 1;
}
void handleField()
{
    for (int i = 0; i < h; i++)
    {
        for (int j = 0; j < w; j++)
        {
            field[i][j] = true;
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = y_1[i]; j <= (y_2[i] - 1); j++)
        {
            for (int k = x_1[i]; k <= (x_2[i] - 1); k++)
            {
                field[j][k] = false;
            }
        }
    }
}
void bfs()
{
    while (!que.empty())
    {
        P p = que.front();
        que.pop();
        for (int i = 0; i < 4; i++)
        {
            int ny = p.first + dy[i];
            int nx = p.second + dx[i];
            if (ny >= 0 && ny < h && nx >= 0 && nx < w && field[ny][nx])
            {
                field[ny][nx] = false;
                que.push(P(ny, nx));
            }
        }
    }
}
void solve()
{
    for (int i = 0; i < h; i++)
    {
        for (int j = 0; j < w; j++)
        {
            if (field[i][j])
            {
                field[i][j] = false;
                que.push(P(i, j));
                bfs();
                ans++;
            }
        }
    }
}
int main()
{
    while (true)
    {
        scanf("%d%d", &w, &h);
        if (w == 0 && h == 0)
        {
            break;
        }
        input();
        compress();
        distinctBy2Posinter();
        handleX_1X_2Y_1Y_2();
        handleField();
        solve();
        printf("%d\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11448
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)

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

vector<int> compress(int *x1, int *x2, int w, int n) {
  vector<int> xs;
  REP(i, n) {
    for (int d = -1; d <= 1; ++d) {
      int tx1 = x1[i] + d, tx2 = x2[i] + d;
      if (0 <= tx1 && tx1 <= w)
        xs.push_back(tx1);
      if (0 <= tx2 && tx2 <= w)
        xs.push_back(tx2);
    }
  }
  sort(xs.begin(), xs.end());
  xs.erase(unique(xs.begin(), xs.end()), xs.end());
  REP(i, n) {
    x1[i] = lower_bound(xs.begin(), xs.end(), x1[i]) - xs.begin();
    x2[i] = lower_bound(xs.begin(), xs.end(), x2[i]) - xs.begin();
  }
  return xs;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int w, h, n;
  while (cin >> w >> h, w) {
    cin >> n;
    vector<vector<bool>> fld(1005 * 6 + 2, vector<bool>(1005 * 6 + 2, false));
    vector<int> x1(n), x2(n), y1(n), y2(n);
    REP(i, n) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
    auto xs = compress(x1.data(), x2.data(), w, n);
    auto ys = compress(y1.data(), y2.data(), h, n);
    REP(i, n) {
      for (int y = y1[i]; y < y2[i]; ++y) {
        for (int x = x1[i]; x < x2[i]; ++x) {
          fld[y][x] = true;
        }
      }
    }
    int ans = 0;
    REP(y, ys.size() - 1) REP(x, xs.size() - 1) {
      if (fld[y][x])
        continue;
      ans++;
      queue<pair<int, int>> q;
      q.push({y, x});
      while (q.size()) {
        auto p = q.front();
        q.pop();
        REP(i, 4) {
          int ny = p.first + dy[i], nx = p.second + dx[i];
          if (ny < 0 || ny >= ys.size() - 1 || nx < 0 || nx >= xs.size() - 1 || fld[ny][nx])
            continue;
          fld[ny][nx] = true;
          q.push({ny, nx});
        }
      }
    }
    cout << ans << "\n";
  }
}
accuracy: 1
time_ms: 40
memory_kb: 8148
final_rank: 3