Nanami is an expert at playing games. This day, Nanami's good friend Hajime invited her to watch a game of baseball. Unwilling as she was, she followed him to the stadium. But Nanami had no interest in the game, so she looked around to see if there was something that might interest her. That's when she saw the digital board at one end of the stadium.

The digital board is n pixels in height and m pixels in width, every pixel is either light or dark. The pixels are described by its coordinate. The j-th pixel of the i-th line is pixel (i, j). The board displays messages by switching a combination of pixels to light, and the rest to dark. Nanami notices that the state of the pixels on the board changes from time to time. At certain times, certain pixels on the board may switch from light to dark, or from dark to light.

Nanami wonders, what is the area of the biggest light block such that a specific pixel is on its side. A light block is a sub-rectangle of the board, in which all pixels are light. Pixel (i, j) belongs to a side of sub-rectangle with (x1, y1) and (x2, y2) as its upper-left and lower-right vertex if and only if it satisfies the logical condition: 

((i = x1 or i = x2) and (y1 ≤ j ≤ y2)) or ((j = y1 or j = y2) and (x1 ≤ i ≤ x2)).

Nanami has all the history of changing pixels, also she has some questions of the described type, can you answer them?

Input

The first line contains three space-separated integers n, m and q (1 ≤ n, m, q ≤ 1000) — the height and width of the digital board, and the number of operations.

Then follow n lines, each line containing m space-separated integers. The j-th integer of the i-th line is ai, j — the initial state of pixel (i, j).

  * If ai, j = 0, pixel (i, j) is initially dark. 
  * If ai, j = 1, pixel (i, j) is initially light. 



Then follow q lines, each line containing three space-separated integers op, x, and y (1 ≤ op ≤ 2; 1 ≤ x ≤ n; 1 ≤ y ≤ m), describing an operation.

  * If op = 1, the pixel at (x, y) changes its state (from light to dark or from dark to light). 
  * If op = 2, Nanami queries the biggest light block with pixel (x, y) on its side. 

Output

For each query, print a single line containing one integer — the answer to Nanami's query.

Examples

Input

3 4 5
0 1 1 0
1 0 0 1
0 1 1 0
2 2 2
2 1 2
1 2 2
1 2 3
2 2 2


Output

0
2
6


Input

3 3 4
1 1 1
1 1 1
1 1 1
2 2 2
1 2 2
2 1 1
2 2 1


Output

6
3
3

Note

Consider the first sample.

The first query specifies pixel (2, 2), which is dark itself, so there are no valid light blocks, thus the answer is 0.

The second query specifies pixel (1, 2). The biggest light block is the block with (1, 2) as its upper-left vertex and (1, 3) as its lower-right vertex.

The last query specifies pixel (2, 2), which became light in the third operation. The biggest light block is the block with (1, 2) as its upper-left vertex and (3, 3) as its lower-right vertex.
import static java.lang.Math.*;
import static java.util.Arrays.*;

import java.util.*;

public class B {

	public B () {
		int n = sc.nextInt();
		sc.nextInt();
		int Q = sc.nextInt();

		int [][][] A = new int [4][][];
		A[0] = sc.nextInts(n);
		for (int i : rep(1, 4))
			A[i] = rotate(A[i-1]);

		int [][] RES = new int [4][Q];
		for (int [] r : RES) fill(r, -1);
		int [][][] L = new int [4][Q][];
		for (int j : rep(Q)) {
			L[0][j] = dec(sc.nextInts());
			for (int i : rep(3)) {
				int [] R = rotate(A[i], L[i][j][1], L[i][j][2]);
				L[i+1][j] = new int [] { L[i][j][0], R[0], R[1] };
			}
		}

		for (int s : rep(4)) {
			int [][] B = A[s]; int N = B.length, M = B[0].length; int [][] P = L[s]; int [] res = RES[s];
			@SuppressWarnings("unchecked")
			TreeMap<Integer, Integer> [] T = new TreeMap[N];
			for (int i : rep(N)) {
				T[i] = new TreeMap<>();
				int p = 0, q = 0;
				while (p < M) {
					while (p < M && B[i][p] == 0) ++p;
					if (p == M) break; q = p;
					while (q < M && B[i][q] == 1) ++q;
					T[i].put(p, q);
					p = q;
				}
			}

			for (int k : rep(Q)) {
				int op = P[k][0], i = P[k][1], j = P[k][2];
				Integer J = T[i].floorKey(j), K = get(T[i], J);

				if (op == 0) {
					if (in(j, J, K)) { // lit!
						int x = J, y = T[i].get(J);
						if (x < j) T[i].put(x, j);
						else T[i].remove(x);
						if (j+1 < y) T[i].put(j+1, y);
					} else { // dark!
						int p = j, q = j+1; Integer U = T[i].higherKey(j), V = get(T[i], U);
						if (in(j-1, J, K)) { p = J; T[i].remove(J); }
						if (in(j+1, U, V)) q = T[i].remove(U);
						T[i].put(p, q);
					}
				} else if (op == 1) {
					int R = 0;
					if (in(j, J, K)) {
						int x = J, y = K; R = y-x;
						for (int p : rep(i+1, N)) {
							Integer U = T[p].floorKey(j), V = get(T[p], U);
							if (in(j, U, V)) {
								x = max(x, U); y = min(y, V);
								R = max(R, (p-i+1) * (y-x));
							}
							else
								break;
						}
					}
					res[k] = R;
				} else
					assert false;
			}
		}

		for (int i : rep(Q))
			if (L[0][i][0] == 1)
				print(maximum(RES[0][i], RES[1][i], RES[2][i], RES[3][i]));
	}

	boolean in (int j, Integer J, Integer K) {
		return J != null && J <= j && j < K;
	}

	private static <T> T [] array (@SuppressWarnings("unchecked") T ... A) { return A; }
	private static int [] dec(int ... A) {
		int [] res = A.clone();
		for (int i = 0; i < A.length; ++i)
			--res[i];
		return res;
	}
	private static <T extends Comparable<T>> int fmax(T [] A) { return fmax(A, 0, A.length); }
	private static <T extends Comparable<T>> int fmax(T [] A, int s, int t) {
		int res = s;
		for (int i = s; i < t; ++i)
			if (A[i].compareTo(A[res]) > 0)
				res = i;
		return res;
	}
	private static <K, V> V get(Map<K, V> map, K key) { return key != null ? map.get(key) : null; }
	private static <T extends Comparable<T>> T maximum(@SuppressWarnings("unchecked") T ... A) { return A[fmax(A)]; }
	private static int [] pri(Integer [] A) { int [] res = new int [A.length]; for (int i = 0; i < A.length; ++i) res[i] = A[i]; return res; }
	private static int [] rep(int N) { return rep(0, N); }
	private static int [] rep(int S, int T) { if (T <= S) return new int [0]; int [] res = new int [T-S]; for (int i = S; i < T; ++i) res[i-S] = i; return res; }
	private static  int [][] rotate (int [][] A) {
		assert A.length > 0 && A[0].length > 0;
		int N = A.length, M = A[0].length;
		int [][] res = new int [M][N];
		for (int i = 0; i < N; ++i)
			for (int j = 0; j < M; ++j) {
				int [] R = rotate(A, i, j);
				res[R[0]][R[1]] = A[i][j];
			}
		return res;
	}
	private static int [] rotate (int [][] A, int i, int j) {
		assert i < A.length && j < A[0].length;
		return pri(array(A[0].length - 1 - j, i));
	}
	////////////////////////////////////////////////////////////////////////////////////
	private final static IOUtils.MyScanner sc = new IOUtils.MyScanner();
	private static void print (Object o, Object ... A) { IOUtils.print(o, A); }
	private static class IOUtils {
		public static class MyScanner {
			public String next() { newLine(); return line[index++]; }
			public int nextInt() { return Integer.parseInt(next()); }
			public String nextLine() { line = null; return readLine(); }
			public String [] nextStrings() { return split(nextLine()); }
			public int [] nextInts() {
				String [] L = nextStrings();
				int [] res = new int [L.length];
				for (int i = 0; i < L.length; ++i)
					res[i] = Integer.parseInt(L[i]);
				return res;
			}
			public int [][] nextInts (int N) {
				int [][] res = new int [N][];
				for (int i = 0; i < N; ++i)
					res[i] = nextInts();
				return res;
			}
			//////////////////////////////////////////////
			private boolean eol() { return index == line.length; }
			private String readLine() {
				try {
					return r.readLine();
				} catch (Exception e) {
					throw new Error (e);
				}
			}
			private final java.io.BufferedReader r;
			private MyScanner () { this(new java.io.BufferedReader(new java.io.InputStreamReader(System.in))); }
			private MyScanner (java.io.BufferedReader r) {
				try {
					this.r = r;
					while (!r.ready())
						Thread.sleep(1);
					start();
				} catch (Exception e) {
					throw new Error(e);
				}
			}
			private String [] line;
			private int index;
			private void newLine() {
				if (line == null || eol()) {
					line = split(readLine());
					index = 0;
				}
			}
			private String [] split(String s) { return s.length() > 0 ? s.split(" ") : new String [0]; }
		}
		private static String build(Object o, Object ... A) { return buildDelim(" ", o, A); }
		private static String buildDelim(String delim, Object o, Object ... A) {
			StringBuilder b = new StringBuilder();
			append(b, o, delim);
			for (Object p : A)
				append(b, p, delim);
			return b.substring(delim.length());
		}
		//////////////////////////////////////////////////////////////////////////////////
		private static void start() { if (t == 0) t = millis(); }
		private static void append(StringBuilder b, Object o, String delim) {
			if (o.getClass().isArray()) {
				int len = java.lang.reflect.Array.getLength(o);
				for (int i = 0; i < len; ++i)
					append(b, java.lang.reflect.Array.get(o, i), delim);
			} else if (o instanceof Iterable<?>)
				for (Object p : (Iterable<?>) o)
					append(b, p, delim);
			else {
				if (o instanceof Double)
					o = new java.text.DecimalFormat("#.############").format(o);
				b.append(delim).append(o);
			}
		}
		private static java.io.PrintWriter pw = new java.io.PrintWriter(System.out);
		private static void print(Object o, Object ... A) { pw.println(build(o, A)); }
		private static void err(Object o, Object ... A) { System.err.println(build(o, A)); }
		private static void exit() {
			IOUtils.pw.close();
			System.out.flush();
			err("------------------");
			err(IOUtils.time());
			System.exit(0);
		}
		private static long t;
		private static long millis() { return System.currentTimeMillis(); }
		private static String time() { return "Time: " + (millis() - t) / 1000.0; }
	}
	public static void main (String[] args) { new B(); IOUtils.exit(); }
}