Problem: The maps in the game are divided into square cells called Geo Panels. Some of these panels are painted. We shall assume that the Geo Panels without color are painted the transparent color. 

Besides, the map has so-called Geo Symbols. They look like pyramids of different colors (including Geo Symbols of the transparent color). Each Geo Symbol is located on one Geo Panel, and each Geo Panel may contain no more than one Geo Symbol. 

Geo Symbols can be eliminated. To understand better what happens when a Geo Symbol is eliminated, let us introduce some queue to which we will put the recently eliminated Geo Symbols. 

Let's put at the head of the queue a Geo Symbol that was eliminated just now. Next, we will repeat the following operation: 

Extract the Geo Symbol from the queue. Look at the color of the panel containing the given Geo Symbol. If it differs from transparent and differs from the color of the Geo Symbol, then all Geo Panels of this color are repainted in the color of the given Geo Symbol (transparent Geo Symbols repaint the Geo Panels transparent). Repainting is executed in an infinite spiral strictly in the following order starting from the panel, which contained the Geo Symbol: 

<image>

In other words, we select all the panels that need to be repainted and find their numbers in the infinite spiral whose center is placed in the position of the given Geo Symbol. After that, we repaint them in the order of the number's increasing. 

If a panel contains another Geo Symbol and this panel is being repainted, then the Geo Symbol is removed from the field and placed at the tail of the queue. 

After repainting the Geo Symbol is completely eliminated and the next Geo Symbol is taken from the head of the queue (if there is any) and the process repeats. The process ends if the queue is empty. 

See the sample analysis for better understanding. 

You know the colors of all the Geo Panels and the location of all the Geo Symbols. Determine the number of repaintings, which will occur if you destroy one of the Geo Symbols.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 300) — the height and the width of the map (in cells).

Then follow n line; each of them contains m numbers — the Geo Panels' colors.

Then follow n more lines; each of them contains m numbers — the Geo Symbols' description. -1 means that the given position contains no Geo Symbol. Otherwise, the number represents the color of the Geo Symbol in the given position.

All colors are integers from 0 to 109. 0 represents the transparent color.

The last line contains two integers x and y (1 ≤ x ≤ n, 1 ≤ y ≤ m) — the row and the column where the Geo Symbol is placed that needs to be eliminated. The rows are numbered from top to bottom, the columns are numbered from left to right. Coordinates are 1-based. It is guaranteed that the position with coordinates (x, y) contains a Geo Symbol.

Output

Print the single number — the total number of repaintings after the Geo Symbol is eliminated. 

Please, do not use the %lld specificator to read or write 64-bit integers in C++. It is preferred to use the cout stream (you may also use the %I64d specificator).

Examples

Input

5 5
9 0 1 1 0
0 0 3 2 0
1 1 1 3 0
1 1 1 3 0
0 1 2 0 3
-1 1 -1 3 -1
-1 -1 -1 0 -1
-1 -1 -1 -1 -1
-1 2 3 -1 -1
-1 -1 -1 -1 2
4 2


Output

35

Note

All actions of the sample you can see on the following picture: 

<image> If your browser does not support APNG and you see just static image, you can see GIF version of this image by the following link:

http://assets.codeforces.com/images/geo_slow.gif

Solution (in JAVA):

Solution:
import java.util.List;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.io.BufferedReader;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author AlexFetisov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskD {

    int[] dx = new int[] {-1, 0, 1, 0};
    int[] dy = new int[] {0, 1, 0, -1};

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int nRows = in.nextInt();
        int nCols = in.nextInt();
        int[][] panelColors = new int[nRows][nCols];
        for (int i = 0; i < nRows; ++i) {
            for (int j = 0; j < nCols; ++j) {
                panelColors[i][j] = in.nextInt();
            }
        }
        int[][] pyColors = new int[nRows][nCols];
        for (int i = 0; i < nRows; ++i) {
            for (int j = 0; j < nCols; ++j) {
                pyColors[i][j] = in.nextInt();
            }
        }
        int xStart = in.nextInt() - 1;
        int yStart = in.nextInt() - 1;

        DisjointSet dsu = new DisjointSet(nRows * nCols);
        int[] colorForGroup = new int[nRows * nCols];
        List<XY>[] pyForGroup = new List[nRows * nCols];
        int[] sizeForGroup = new int[nRows * nCols];

        HashMap<Integer, List<XY>> allColorsToPoints = new HashMap<Integer, List<XY>>();
        for (int i = 0; i < nRows; ++i) {
            for (int j = 0; j < nCols; ++j) {
                int c = panelColors[i][j];
                List<XY> list;
                if (allColorsToPoints.containsKey(c)) {
                    list = allColorsToPoints.get(c);
                } else {
                    list = new ArrayList<XY>(1);
                }
                list.add(new XY(i, j));
                allColorsToPoints.put(c, list);
            }
        }
        for (int i = 0; i < nRows * nCols; ++i) {
            pyForGroup[i] = new ArrayList<XY>();
        }
        HashMap<Integer, Integer> colorForRep = new HashMap<Integer, Integer>();

        for (int color : allColorsToPoints.keySet()) {
            List<XY> xy = allColorsToPoints.get(color);
            int first = xy.get(0).x * nCols + xy.get(0).y;
            for (int i = 1; i < xy.size(); ++i) {
                int pi = xy.get(i).x * nCols + xy.get(i).y;
                dsu.union(first, pi);
                first = dsu.findSet(first);
            }
            first = dsu.findSet(first);
            colorForGroup[first] = color;
            sizeForGroup[first] = xy.size();
            pyForGroup[first] = new ArrayList<XY>();
            colorForRep.put(color, first);
            for (XY el : xy) {
                if (pyColors[el.x][el.y] != -1) {
                    pyForGroup[first].add(el);
                }
            }
        }

        List<XY> q = new LinkedList<XY>();
        q.add(new XY(xStart, yStart));

        long res = 0;

        final HashMap<XY, Integer> orderMap = new HashMap<XY, Integer>();
        int cx = 0;
        int cy = 0;
        int dir = 0;
        int side = 1;
        int order = 0;

        for (int iter = 0; iter < 1200; ++iter) {
            for (int i = 0; i < side; ++i) {
                if (cx >= -300 && cy >= -300 && cx <= 300 && cy <= 300) {
                    orderMap.put(new XY(cx, cy), order++);
                }
                cx += dx[dir];
                cy += dy[dir];
            }
            ++dir;
            if (dir == 4) dir = 0;
            if (iter % 2 == 1 && iter > 0) {
                ++side;
            }
        }
        HashSet<XY> was = new HashSet<XY>();
        was.add(new XY(xStart, yStart));

        while (!q.isEmpty()) {
            final XY cur = q.get(0);
            q.remove(0);
            int el = cur.x * nCols + cur.y;
            int rep = dsu.findSet(el);
            Integer repPyColor = colorForRep.get(pyColors[cur.x][cur.y]);


            int curColorUnder = colorForGroup[rep];
            if (curColorUnder != pyColors[cur.x][cur.y] && curColorUnder != 0 && pyColors[cur.x][cur.y] != -1) {
                res += sizeForGroup[rep];

                Collections.sort(pyForGroup[rep], new Comparator<XY>() {
                    public int compare(XY o1, XY o2) {
                        int x1 = o1.x - cur.x;
                        int y1 = o1.y - cur.y;
                        int x2 = o2.x - cur.x;
                        int y2 = o2.y - cur.y;
                        int order1 = orderMap.get(new XY(x1, y1));
                        int order2 = orderMap.get(new XY(x2, y2));
                        return order1 - order2;
                    }
                });

                for (XY p : pyForGroup[rep]) {
                    if (!was.contains(p)) {
                        q.add(p);
                        was.add(p);
                    }
                }

                if (repPyColor == null) {
                    colorForGroup[rep] = pyColors[cur.x][cur.y];
                    colorForRep.put(pyColors[cur.x][cur.y], rep);
                    pyForGroup[rep].clear();
                    colorForRep.remove(curColorUnder);
                } else {
                    int newSize = sizeForGroup[rep] + sizeForGroup[repPyColor];
                    List<XY> old = pyForGroup[repPyColor];
                    dsu.union(rep, repPyColor);
                    rep = dsu.findSet(rep);
                    colorForGroup[rep] = pyColors[cur.x][cur.y];
                    colorForRep.put(pyColors[cur.x][cur.y], rep);
                    pyForGroup[rep] = old;
                    sizeForGroup[rep] = newSize;

                    colorForRep.remove(curColorUnder);
                }
            }
        }
        out.println(res);
    }

    class XY {
        int x, y;

        public XY(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            XY xy = (XY) o;

            if (x != xy.x) return false;
            if (y != xy.y) return false;

            return true;
        }

        public int hashCode() {
            int result = x;
            result = 31 * result + y;
            return result;
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(nextString());
    }

}

class DisjointSet {
    int[] parent;
    int[] rank;

    public DisjointSet(int size) {
        parent = new int[size];
        rank = new int[size];
        for (int i = 0; i < size; ++i) {
            parent[i] = i;
            rank[i] = 0;
        }
    }

    public int findSet(int x) {
        if (parent[x] != x) {
            parent[x] = findSet(parent[x]);
        }
        return parent[x];
    }

    public boolean union(int x, int y) {
        x = findSet(x);
        y = findSet(y);
        if (x != y) {
            if (rank[x] < rank[y]) {
                parent[x] = y;
            } else {
                parent[y] = x;
                if (rank[x] == rank[y]) {
                    ++rank[x];
                }
            }
            return true;
        }
        return false;
    }
}