// Arup Guha
// 10/22/2016
// Solution to 2016 NCPC Problem A: Artwork
// Solved during UCF practice teaming with Travis Meade (who came up with this solution idea).

import java.util.*;
import java.io.*;

public class a {
	
	public static int[] DX = {-1,0,0,1};
	public static int[] DY = {0,-1,1,0};
	
	public static int r;
	public static int c;
	public static int numQ;
	public static int[][] grid;
	public static int[] res;
	public static int numBlack;
	
	public static int[][] moves;
	
	public static void main(String[] Args) throws Exception {

		// Set everything up.
		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer tok = new StringTokenizer(stdin.readLine());
		r = Integer.parseInt(tok.nextToken());
		c = Integer.parseInt(tok.nextToken());
		numQ = Integer.parseInt(tok.nextToken());
		res = new int[numQ];
		grid = new int[r][c];
		
		for (int i=0; i<r; i++)
			Arrays.fill(grid[i], -1);
		numBlack = 0;
		
		moves = new int[numQ][4];
		
		// Process queries.
		for (int i=0; i<numQ; i++) {
			
			// Read in this move.
			tok = new StringTokenizer(stdin.readLine());
			int x1 = Integer.parseInt(tok.nextToken())-1;
			int y1 = Integer.parseInt(tok.nextToken())-1;
			int x2 = Integer.parseInt(tok.nextToken())-1;
			int y2 = Integer.parseInt(tok.nextToken())-1;
			moves[i][0] = x1;
			moves[i][1] = y1;
			moves[i][2] = x2;
			moves[i][3] = y2;
			
			// Vertical - fill in.
			if (x1 == x2) {
				for (int j=y1; j<=y2; j++)
					if (grid[x1][j] == -1) {
						grid[x1][j] = i;
						numBlack++;
					}
			}
			
			// Horizontal - fill in.
			else {
				for (int j=x1; j<=x2; j++)
					if (grid[j][y1] == -1) {
						grid[j][y1] = i;
						numBlack++;
					}
			}
		}
		
		// Set up a Disjoint Set
		dj set = new dj(r*c);
		for (int i=0; i<r; i++) {
			for (int j=0; j<c; j++) {
				
				// For a non-painted square, just union it with its non-painted neighbors (same region)
				if (grid[i][j] == -1) {
					for (int k=0; k<DX.length; k++)
						if (inbounds(i+DX[k], j+DY[k]) && grid[i+DX[k]][j+DY[k]] == -1)
							set.union(i*c+j, (i+DX[k])*c + j+DY[k]);
				}
			}
		}
		
		// This is our LAST answer, store it.
		res[numQ-1] = set.numC - numBlack;
		
		// Do each move backwards.
		for (int i=numQ-1; i>0; i--) {
			
			// Store the move.
			int x1 = moves[i][0];
			int y1 = moves[i][1];
			int x2 = moves[i][2];
			int y2 = moves[i][3];
			
			// A vertical "undraw"
			if (x1 == x2) {
				
				// Check to see if this was the first time this square was painted - 
				// if so it's a non-painted square that must be unioned with its neighbors.
				for (int j=y1; j<=y2; j++)
					if (grid[x1][j] == i) {
						grid[x1][j] = -1;
						numBlack--;
						for (int k=0; k<DX.length; k++) 
							if (inbounds(x1+DX[k], j+DY[k]) && grid[x1+DX[k]][j+DY[k]] == -1)
								set.union(x1*c+j, (x1+DX[k])*c+j+DY[k]);
					}
			}
			
			// A horizontal "undraw"
			else {
				
				// Same deal as the vertical case...
				for (int j=x1; j<=x2; j++)
					if (grid[j][y1] == i) {
						grid[j][y1] = -1;
						numBlack--;
						for (int k=0; k<DX.length; k++)
							if (inbounds(j+DX[k], y1+DY[k]) && grid[j+DX[k]][y1+DY[k]] == -1)
								set.union(j*c+y1, (j+DX[k])*c+y1+DY[k]);
					}
			}
			
			// Store this result.
			res[i-1] = set.numC - numBlack;
		}
		
		// Store all answers in one string and output.
		StringBuffer str = new StringBuffer();
		for (int i=0; i<numQ; i++)
			str.append(res[i]+"\n");
		System.out.print(str);
		
	}
	
	public static boolean inbounds(int x, int y) {
		return x >= 0 && x < r && y >= 0 && y < c;
	}
}

// My disjoint set which also keeps track of the total number of components.
class dj {
	
	public int n;
	public int[] par;
	public int[] height;
	public int numC;
	
	public dj(int size) {
		n = size;
		par = new int[size];
		height = new int[size];
		
		for (int i=0; i<size; i++)
			par[i] = i;
		numC = n;
	}
	
	public boolean union(int a, int b) {
		int para = find(a);
		int parb = find(b);
		if (para == parb) return false;
		
		if (height[para] < height[parb]) {
			par[para] = parb;
		}
		else if (height[parb] < height[para]) {
			par[parb] = para;
		}
		else {
			par[para] = parb;
			height[parb]++;
		}
		numC--;
		return true;
	}
	
	public int find(int a) {
		if (par[a] == a) return a;
		return find(par[a]);
	}
}