Bob has a rectangular chocolate bar of the size W × H. He introduced a cartesian coordinate system so that the point (0, 0) corresponds to the lower-left corner of the bar, and the point (W, H) corresponds to the upper-right corner. Bob decided to split the bar into pieces by breaking it. Each break is a segment parallel to one of the coordinate axes, which connects the edges of the bar. More formally, each break goes along the line x = xc or y = yc, where xc and yc are integers. It should divide one part of the bar into two non-empty parts. After Bob breaks some part into two parts, he breaks the resulting parts separately and independently from each other. Also he doesn't move the parts of the bar. Bob made n breaks and wrote them down in his notebook in arbitrary order. At the end he got n + 1 parts. Now he wants to calculate their areas. Bob is lazy, so he asks you to do this task.

Input

The first line contains 3 integers W, H and n (1 ≤ W, H, n ≤ 100) — width of the bar, height of the bar and amount of breaks. Each of the following n lines contains four integers xi, 1, yi, 1, xi, 2, yi, 2 — coordinates of the endpoints of the i-th break (0 ≤ xi, 1 ≤ xi, 2 ≤ W, 0 ≤ yi, 1 ≤ yi, 2 ≤ H, or xi, 1 = xi, 2, or yi, 1 = yi, 2). Breaks are given in arbitrary order.

It is guaranteed that the set of breaks is correct, i.e. there is some order of the given breaks that each next break divides exactly one part of the bar into two non-empty parts.

Output

Output n + 1 numbers — areas of the resulting parts in the increasing order.

Examples

Input

2 2 2
1 0 1 2
0 1 1 1


Output

1 1 2 

Input

2 2 3
1 0 1 2
0 1 1 1
1 1 2 1


Output

1 1 1 1 

Input

2 4 2
0 1 2 1
0 3 2 3


Output

2 2 4 
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class R031D {
    public void debug(Object... objects) { System.err.println(Arrays.deepToString(objects)); }
    public static final int INF = 987654321;
    public static final long LINF = 987654321987654321L;
    public static final double EPS = 1e-9;
    
    boolean isEqual(long a, long b) { return a == b; }
    boolean isEqual(Point p1, Point p2) { return p1.equals(p2); }
    
    class Point {
        // 点クラス
        long x, y;
        public Point(long x, long y) { this.x = x; this.y = y; }
        public Point(Point p) { this(p.x, p.y); }
        public long lengthSquare() { return x * x + y * y; }
        public int hashCode() { return (int)(x * 17) + (int)(y * 31); }
        public boolean equals(Object o) {
            if(!(o instanceof Point)) return false;
            Point that = (Point)o;
            return isEqual(this.x, that.x) && isEqual(this.y , that.y);
        }
        public String toString() { return x + ", " + y; }
    }
    
    class Segment {
        // 線分クラス
        Point p1, p2;
        public Segment(Point p1, Point p2) { this.p1 = p1; this.p2 = p2; }
        public Segment(long x1, long y1, long x2, long y2) { this(new Point(x1, y1), new Point(x2, y2)); }
        /** 引数の線分と同じ線分かどうか */
        public boolean isSameSegment(Segment that) { return this.equals(that); }
        /** 引数の線分と同じ端点を持つかどうか */
        public boolean hasCommonEndpoint(Segment that) {
            if(this.p1.equals(that.p1)) return true;
            if(this.p1.equals(that.p2)) return true;
            if(this.p2.equals(that.p1)) return true;
            if(this.p2.equals(that.p2)) return true;
            return false;
        }
        /** 引数の線分と同じ端点を持つ場合、その端点を求める */
        public Point getCommonEndpoint(Segment that) {
            if(!hasCommonEndpoint(that)) return null;
            if(this.p1.equals(that.p1)) return new Point(this.p1);
            if(this.p1.equals(that.p2)) return new Point(this.p1);
            if(this.p2.equals(that.p1)) return new Point(this.p2);
            if(this.p2.equals(that.p2)) return new Point(this.p2);
            return null;
        }
        /** 引数の点が終端かどうか */
        boolean isPointAtEnding(Point p) { return p.equals(p1) || p.equals(p2); }
        /** 引数の点が線分上にあるかどうか */
        boolean isPointOnSegment(Point p) {
            long d, x1=p1.x, y1=p1.y, x2=p2.x, y2=p2.y;
            if(x1 > x2) {
                d = x1; x1 = x2; x2 = d;
                d = y1; y1 = y2; y2 = d;
            }
            return x1 <= p.x && p.x <= x2 &&
                   ( (y1 <= y2 && y1 <= p.y && p.y <= y2) ||
                     (y1 > y2 && y2 <= p.y && p.y <= y1) ) &&
                     (p.y-y1)*(x2-x1) == (y2-y1)*(p.x-x1);
        }
        public long lengthSquare() { return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y); }
        public int hashCode() { return p1.hashCode() + p2.hashCode(); }
        public boolean equals(Object o) {
            if(!(o instanceof Segment)) return false;
            Segment that = (Segment)o;
            return (isEqual(this.p1, that.p1) && isEqual(this.p2, that.p2)) || 
                   (isEqual(this.p1, that.p2) && isEqual(this.p2, that.p1));
        }    
        public String toString() { return "(" + p1 + " : " + p2 + ")"; }
    }
    
    class Rectangle implements Comparable<Rectangle>{
        Point p1, p2;   // p1: 左下, p2: 右上 [:<]
        Rectangle(Point p1, Point p2) { this.p1 = p1; this.p2 = p2; }
        Rectangle(long x1, long y1, long x2, long y2) { this(new Point(x1, y1), new Point(x2, y2)); }
        long getArea() { return (p2.x - p1.x) * (p2.y - p1.y); }
        Rectangle cut(Segment seg) {
            Segment a = new Segment(this.p1.x, this.p1.y, this.p2.x, this.p1.y);
            Segment b = new Segment(this.p1.x, this.p1.y, this.p1.x, this.p2.y);
            Segment c = new Segment(this.p2.x, this.p1.y, this.p2.x, this.p2.y);
            Segment d = new Segment(this.p1.x, this.p2.y, this.p2.x, this.p2.y);
            if (a.isPointOnSegment(seg.p1) && d.isPointOnSegment(seg.p2)) {
                Point temp = this.p2;
                this.p2 = seg.p2;
                return new Rectangle(seg.p1, temp);
            } else if (a.isPointOnSegment(seg.p2) && d.isPointOnSegment(seg.p1)) {
                Point temp = this.p2;
                this.p2 = seg.p1;
                return new Rectangle(seg.p2, temp);
            } else if (b.isPointOnSegment(seg.p1) && c.isPointOnSegment(seg.p2)) {
                Point temp = this.p2;
                this.p2 = seg.p2;
                return new Rectangle(seg.p1, temp);
            } else if (b.isPointOnSegment(seg.p2) && c.isPointOnSegment(seg.p1)) {
                Point temp = this.p2;
                this.p2 = seg.p1;
                return new Rectangle(seg.p2, temp);
            } else {
                return null;
            }
        }
        public int compareTo(Rectangle that) {
            if(this.getArea() == that.getArea()) return 0;
            return this.getArea() > that.getArea() ? 1 : -1;
        }
        public String toString() { return "[" + p1 + ", " + p2 + "]"; }
    }

    
    
    public R031D() {
        Scanner scanner = new Scanner(System.in);
        List<Rectangle> array = new LinkedList<Rectangle>();
        long w = scanner.nextLong();
        long h = scanner.nextLong();
        array.add(new Rectangle(0, 0, w, h));
        int n = scanner.nextInt();
        Segment[] segs = new Segment[n];
        boolean[] used = new boolean[n];
        for(int i=0; i<n; i++) {
            long x1 = scanner.nextLong();
            long y1 = scanner.nextLong();
            long x2 = scanner.nextLong();
            long y2 = scanner.nextLong();
            segs[i] = new Segment(x1, y1, x2, y2);
        }
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(!used[j]) {
                    for(int k=0; k<array.size(); k++) {
                        Rectangle rect = array.get(k).cut(segs[j]);
                        if(rect == null) { continue; }
                        array.add(rect);
                        used[j] = true;
                        break;
                    }
                    if(used[j]) { break; }
                }
            }
        }
        Collections.sort(array);
        for(int i=0; i<array.size(); i++) {
            System.out.print(array.get(i).getArea() + " ");
        }
    }
    
    private void solve() {
    }
    
    public static void main(String[] args) { new R031D().solve(); }
}
