// Arup Guha
// 4/11/2013
// Solution to 2013 Chicago Invitational Contest Problem I: Unreal Estate

/* Note: My solution takes close to a minute. It's possible that there are some
 *       inefficiencies in my segment tree. But, I believe my segment tree code
 *       runs in O(lg n) for a single insert and single delete.
 */
 
import java.util.*;

public class i {

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);

		int n = stdin.nextInt();

		while (n != 0) {

			double[] xVals = new double[2*n];
			double[] yVals = new double[2*n];

			rectangle[] boxes = new rectangle[n];
			for (int i=0; i<n; i++) {
				double x1 = stdin.nextDouble();
				double y1 = stdin.nextDouble();
				double x2 = stdin.nextDouble();
				double y2 = stdin.nextDouble();
				boxes[i] = new rectangle(x1, y1, x2, y2, i);
				xVals[2*i] = x1;
				xVals[2*i+1] = x2;
				yVals[2*i] = y1;
				yVals[2*i+1] = y2;
			}

			// Get these sorted.
			xVals = fix(xVals);
			yVals = fix(yVals);

			// Create HashMaps so we can do reverse lookups.
			HashMap<Double, Integer> lookUpX = makeLookUp(xVals);
			HashMap<Double, Integer> lookUpY = makeLookUp(yVals);

			// Add lookup info directly into rectangles.
			for (int i=0; i<n; i++) {
				boxes[i].xLIndex = lookUpX.get(boxes[i].xLeft);
				boxes[i].xRIndex = lookUpX.get(boxes[i].xRight);
				boxes[i].yLIndex = lookUpY.get(boxes[i].yLeft);
				boxes[i].yRIndex = lookUpY.get(boxes[i].yRight);
			}

			// Will store which rectangles start and end at which x values
			LinkedList[] starting = new LinkedList[xVals.length];
			LinkedList[] ending = new LinkedList[xVals.length];
			for (int i=0; i<xVals.length; i++) {
				starting[i] = new LinkedList<Integer>();
				ending[i] = new LinkedList<Integer>();
			}

			for (int i=0; i<n; i++) {
				starting[lookUpX.get(boxes[i].xLeft)].add(i);
				ending[lookUpX.get(boxes[i].xRight)].add(i);
			}

			segtree mySegTree = new segtree(yVals);

			// Initialize segment tree.
			for (int i=0; i<starting[0].size(); i++) {
				int thisBox = (Integer)starting[0].get(i);
				mySegTree.insert(thisBox, boxes[thisBox].yLIndex, boxes[thisBox].yRIndex);
			}

			double area = 0;

			// Now, range through each x-value, looking at slice x(i-1) to x(i).
			for (int i=1; i<xVals.length; i++) {

				area = area + (xVals[i] - xVals[i-1])*mySegTree.sumRanges();

				// Add in new rectangles.
				for (int j=0; j<starting[i].size(); j++) {
					int thisBox = (Integer)starting[i].get(j);
					mySegTree.insert(thisBox, boxes[thisBox].yLIndex, boxes[thisBox].yRIndex);
				}

				// Subtract out old rectangles.
				for (int j=0; j<ending[i].size(); j++) {
					int thisBox = (Integer)ending[i].get(j);
					mySegTree.delete(thisBox, boxes[thisBox].yLIndex, boxes[thisBox].yRIndex);
				}
			}

			System.out.printf("%.2f\n", area);

			n = stdin.nextInt();
		}
	}

	public static HashMap<Double,Integer> makeLookUp(double[] values) {
		HashMap<Double,Integer> table = new HashMap<Double,Integer>();
		for (int i=0; i<values.length; i++)
			table.put(values[i], i);
		return table;
	}

	// Sorts and removes duplicates.
	public static double[] fix(double[] a) {

		Arrays.sort(a);
		int cnt = 1;
		for (int i=1; i<a.length; i++)
			if (a[i] > a[i-1])
				cnt++;

		double[] ans = new double[cnt];
		ans[0] = a[0];
		cnt = 1;
		for (int i=1; i<a.length; i++) {
			if (a[i] > a[i-1]) {
				ans[cnt] = a[i];
				cnt++;
			}
		}

		return ans;
	}
}

class rectangle {

	public double xLeft;
	public double yLeft;
	public double xRight;
	public double yRight;
	public int xLIndex;
	public int xRIndex;
	public int yLIndex;
	public int yRIndex;

	public int ID;

	public rectangle(double x1, double y1, double x2, double y2, int index) {
		xLeft = x1;
		yLeft = y1;
		xRight = x2;
		yRight = y2;
		ID = index;
	}
}

class segtree {

	public HashSet[] segTree;
	public int range;
	public double[] values;

	public segtree(double[] sortedList) {

		// Implicitly, range starts and 0.
		int n = sortedList.length;
		range = powTwo(n);

		// Allocate our space here.
		segTree = new HashSet[getLen(n)];
		for (int i=0; i<segTree.length; i++)
			segTree[i] = new HashSet<Integer>();

		// Need to store these to calculate effective range.
		values = new double[range+1];
		for (int i=0; i<sortedList.length; i++)
			values[i] = sortedList[i];
		for (int i=sortedList.length; i<values.length; i++)
			values[i] = sortedList[sortedList.length-1];
	}

	public double sumRanges() {
		return sumRangesRec(0, 0, range);
	}

	private double sumRangesRec(int root, int startIndex, int numVals) {

		//System.out.println("root is "+root+" and start is "+startIndex);

		// Nothing in this branch, breakout.
		if (root >= segTree.length) return 0;

		// Non null node, count whole range.
		if (segTree[root].size() > 0)
			return values[startIndex+numVals] - values[startIndex];

		// Add the rest.
		return sumRangesRec(2*(root+1)-1, startIndex, numVals/2) + sumRangesRec(2*root+2, startIndex+numVals/2, numVals/2);
	}

	public void insert(int ID, int start, int end) {
		insertRec(0, 0, range, ID, start, end);
	}

	private void insertRec(int root, int startIndex, int numVals, int ID, int start, int end) {

		// We have found range!
		if (start == startIndex && end == startIndex+numVals) {
			segTree[root].add(ID);
		}

		// Just go left.
		else if (start >= startIndex + numVals/2)
			insertRec(2*root+2, startIndex+numVals/2, numVals/2, ID, start, end);

		// Go right.
		else if (end <= startIndex + numVals/2)
			insertRec(2*root+1, startIndex, numVals/2, ID, start, end);

		// Must go in both directions.
		else {
			insertRec(2*root+1, startIndex, numVals/2, ID, start, startIndex+numVals/2);
			insertRec(2*root+2, startIndex+numVals/2, numVals/2, ID, startIndex+numVals/2, end);
		}
	}

	public void delete(int ID, int start, int end) {
		deleteRec(0, 0, range, ID, start, end);
	}

	private void deleteRec(int root, int startIndex, int numVals, int ID, int start, int end) {

		// We have found range!
		if (start == startIndex && end == startIndex+numVals) {
			segTree[root].remove(new Integer(ID));
		}

		// Delete to left.
		else if (start >= startIndex + numVals/2)
			deleteRec(2*root+2, startIndex+numVals/2, numVals/2, ID, start, end);

		// Delete to right.
		else if (end <= startIndex + numVals/2)
			deleteRec(2*root+1, startIndex, numVals/2, ID, start, end);

		else {
			deleteRec(2*root+1, startIndex, numVals/2, ID, start, startIndex+numVals/2);
			deleteRec(2*root+2, startIndex+numVals/2, numVals/2, ID, startIndex+numVals/2, end);
		}
	}


	// Returns length of segment tree for int n. Actual range will be [0, 2^ceil(log n)-1].
	private static int getLen(int n) {

		int cnt = 1;
		while (cnt < n)
			cnt *= 2;

		return 2*cnt-1;
	}

	private static int powTwo(int n) {

		int cnt = 1;
		while (cnt < n)
			cnt *= 2;

		return cnt;
	}
}