1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#define NDEBUG
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <list>
using namespace std;
#define TRACE(x) cerr<<"# "#x<<endl;
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<endl;
typedef unsigned long long ULL;
typedef long long LL;
const int INF = 0x7FFFFFFF;


struct Tribe {
	int x1, x2, y1, y2;

	Tribe(int a, int b, int c, int d): x1(a), x2(b), y1(c), y2(d) {}
};

int main() {
	int n, x1, x2, y1, y2;
	vector<Tribe> tribes;
	
	scanf("%d", &n);
	tribes.reserve(n + 1);

	for(int i=0; i<n ;++i) {
		scanf("%d %d %d %d", &x1, &x2, &y1, &y2);
		tribes.emplace_back( Tribe(x1,x2,y1,y2) );
	}

	sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool { return a.x1 < b.x1; });

	#define GO_BACK 0
		
		auto start = tribes.begin();

	#if ! GO_BACK
		START:
	#endif
		for(auto first=start; first < tribes.end() ;++first) {
	#if GO_BACK
			START:
	#endif
			#ifndef NDEBUG
			fprintf(stderr, "first   x: %d - %d     y: %d - %d\n", first->x1, first->x2, first->y1, first->y2);
			#endif
			for(auto second=(first+1); second < tribes.end() ;++second) {
				#ifndef NDEBUG
				fprintf(stderr, "  second   x: %d - %d     y: %d - %d\n", second->x1, second->x2, second->y1, second->y2);
				#endif
				if(second->x1 < first->x2) {
					if(second->y1 < first->y2) {
						if(second->y2 > first->y1) {
							// intersection - merge
							#ifndef NDEBUG
							fprintf(stderr, "    merge\n");
							#endif

							first->x2 = max(first->x2 , second->x2);
							first->y1 = min(first->y1 , second->y1);
							first->y2 = max(first->y2 , second->y2);
							tribes.erase(second);
	#if GO_BACK
							int left = min(first->x1,);
							while((first != start) && (first->x2 >= left)) {
								--first;
							}
	#endif
							goto START;
							
						}
					}
				} else {
					#ifndef NDEBUG
					fprintf(stderr, "      no more intersections possible\n");
					#endif
					break;
				}
			}
		}


	sort(tribes.begin(), tribes.end(), [](const Tribe &a, const Tribe &b) -> bool {
			if(a.x1 < b.x1) {
				return true;
			} else if(a.x1 == b.x1) {
				if(a.x2 < b.x2) {
					return true;
				} else if(a.x2 == b.x2) {
					if(a.y1 < b.y1) {
						return true;
					} else if(a.y1 == b.y1) {
						return (a.y2 < b.y2);
					}
				}
			}
			return false;
		});

	printf("%u\n", static_cast<unsigned>(tribes.size()));
	for( const auto &t : tribes) {
		printf("%d %d %d %d\n", t.x1, t.x2, t.y1, t.y2);
	}	
	
	return 0;
}