import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.TreeSet;
class Main {
int width, height;
Size(int width, int height) {
this.width = width;
this.height = height;
}
int getArea() {
return width * height;
}
Size intersect(Size size) {
return new Size
(Math.
min(width, size.
width),
Math.
min(height, size.
height)); }
boolean contain(Size size) {
return size.width <= width && size.height <= height;
}
@Override
public int compareTo
(Object object
) { Size size = (Size)object;
int area = getArea();
int anotherArea = size.getArea();
if (area == anotherArea) {
if (width == size.width) {
return height - size.height;
} else {
return width - size.width;
}
} else {
return area - anotherArea;
}
}
}
boolean[][] components;
Matrix(boolean[][] components) {
this.components = components;
}
void convolve(int columns, int rows) {
if (columns > 0) {
for (int y = 0; y < components.length; y++) {
int length = columns;
for (int x = components[0].length - 1; x >= 0; x--) {
if (components[y][x]) {
length = columns;
} else if (length > 0) {
components[y][x] = true;
length--;
}
}
}
}
if (rows > 0) {
for (int x = 0; x < components[0].length; x++) {
int length = rows;
for (int y = components.length - 1; y >= 0; y--) {
if (components[y][x]) {
length = rows;
} else if (length > 0) {
components[y][x] = true;
length--;
}
}
}
}
}
int countup() {
int count = 0;
for (int y = 0; y < components.length; y++) {
for (int x = 0; x < components[0].length; x++) {
if (!components[y][x]) {
count++;
}
}
}
return count;
}
@Override
public Matrix clone() {
Matrix matrix = null;
try {
matrix = (Matrix)super.clone();
matrix.components = new boolean[components.length][components[0].length];
for (int y = 0; y < components.length; y++) {
for (int x = 0; x < components[0].length; x++) {
matrix.components[y][x] = components[y][x];
}
}
return matrix;
}
}
boolean widget;
Size size;
List<Node> children;
Node(boolean widget, Size size) {
this.widget = widget;
this.size = size;
children = new ArrayList<Node>();
}
void visit(Matrix parentMatrix, Size parentSize) {
Matrix matrix = parentMatrix.clone();
matrix.convolve(size.width - parentSize.width, size.height - parentSize.height);
if (widget) {
counts
[size.
height][size.
width] = new Integer(matrix.
countup()); }
ListIterator<Node> iter = children.listIterator();
while (iter.hasNext()) {
iter.next().visit(matrix, size);
}
}
@Override
public int compareTo
(Object object
) { return size.compareTo(((Node)object).size);
}
}
new Main().run();
}
final static int MAX_WIDTH = 300;
final static int MAX_HEIGHT = 300;
final static Integer[][] counts
= new Integer[MAX_HEIGHT
+ 1][MAX_WIDTH
+ 1];
Matrix homeMatrix = new Matrix(readHome(readSize(in), in));
int number
= Integer.
parseInt(in.
readLine()); Size[] widgets = new Size[number];
for (int i = 0; i < number; i++) {
widgets[i] = readSize(in);
}
TreeSet<Node> nodeSet = new TreeSet<Node>();
for (int i = 0; i < number; i++) {
nodeSet.add(new Node(true, widgets[i]));
}
for (int i = 0; i < number; i++) {
for (int j = i + 1; j < number; j++) {
nodeSet.add(new Node(false, widgets[i].intersect(widgets[j])));
}
}
Size rootSize = new Size(1, 1);
nodeSet.add(new Node(false, rootSize));
List<Node> nodes = new ArrayList<Node>(nodeSet);
for (int i = nodes.size() - 1; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (nodes.get(i).size.contain(nodes.get(j).size)) {
nodes.get(j).children.add(nodes.get(i));
break;
}
}
}
nodes.get(0).visit(homeMatrix, rootSize);
for (int i = 0; i < widgets.length; i++) {
Size widget = widgets[i];
System.
out.
println(counts
[widget.
height][widget.
width]); }
}
String[] tokens
= in.
readLine().
split(" "); int width
= Integer.
parseInt(tokens
[1]); int height
= Integer.
parseInt(tokens
[0]); return new Size(width, height);
}
boolean[][] components = new boolean[size.height][size.width];
for (int y = 0; y < size.height; y++) {
for (int x = 0; x < size.width; x++) {
components[y][x] = line.charAt(x) == '1';
}
}
return components;
}
static void print(boolean[][] components) {
for (int y = 0; y < components.length; y++) {
for (int x = 0; x < components[0].length; x++) {
char digit;
if (components[y][x]) {
digit = '1';
} else {
digit = '0';
}
}
}
}
static void print(Node node, int spaces) {
for (int i = 0; i < spaces; i++) {
}
if (node.widget) {
} else {
}
System.
out.
print(node.
size.
width); System.
out.
print(node.
size.
height); if (node.widget) {
} else {
}
ListIterator<Node> iter = node.children.listIterator();
while (iter.hasNext()) {
print(iter.next(), spaces + 1);
}
}
}