105_D. Entertaining Geodetics_13806
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
import java.io.*;
import java.util.*;

public class D {

    BufferedReader br;
    PrintWriter out;
    StringTokenizer st;
    boolean eof;
    
    void makeUnique(ArrayList<Integer> ls) {
        Collections.sort(ls);
        
        int uk = 0;
        
        for (int i = 0; i < ls.size(); i++)
            if (ls.get(i).compareTo(ls.get(uk)) != 0)
                ls.set(++uk, ls.get(i));
        
        for (int i = ls.size() - 1; i > uk; i--)
            ls.remove(i);
    }
    
    class Cell implements Comparable<Cell>{
        int order;
        int x;
        int y;
        
        public Cell(int x, int y, int x0, int y0) {
            this.x = x;
            this.y = y;
            
            x -= x0;
            y -= y0;
            if (x == 0 && y == 0) {
                this.order = 1;
                return;
            }
            
            int layer = Math.max(Math.abs(x), Math.abs(y));
            this.order = (2 * layer - 1) * (2 * layer - 1);
            if (x == -layer && y != -layer)
                this.order += (y + layer);
            else if (y == layer)
                this.order += (2 * layer) + layer + x;
            else if (x == layer)
                this.order += (4 * layer) + layer - y;
            else
                this.order += (6 * layer) + layer - x;

        }

        @Override
        public int compareTo(Cell o) {
            return order - o.order;
        }
        
    }
    
    int get(int x, int[] p) {
        return x == p[x] ? x : (p[x] = get(p[x], p));
    }

    void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        
        ArrayList<Integer> all = new ArrayList<Integer>();
        
        all.add(0);
        
        int[][] f = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                f[i][j] = nextInt();
                all.add(f[i][j]);
            }
        
        int[][] symb = new int[n][m];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                symb[i][j] = nextInt();
                if (symb[i][j] != -1)
                    all.add(symb[i][j]);
            }
        
        makeUnique(all);
        
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                f[i][j] = Collections.binarySearch(all, f[i][j]);
                if (symb[i][j] != -1)
                    symb[i][j] = Collections.binarySearch(all, symb[i][j]);
            }

        int z = all.size();
        
        ArrayList<Integer>[] list = new ArrayList[all.size()];
        for (int i = 0; i < list.length; i++) {
            list[i] = new ArrayList<Integer>();
        }
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                list[f[i][j]].add(i * m + j);
        
        int[] p = new int[z];
        int[] sz = new int[z];
        int[] root = new int[z];
        int[] col = new int[z];
        boolean[] wasCleared = new boolean[z];
        
        for (int i = 0; i < z; i++) {
            p[i] = i;
            sz[i] = list[i].size();
        }
        root = p.clone();
        col = p.clone();
        
        ArrayDeque<Integer> q = new ArrayDeque<Integer>();
        
        int x0 = nextInt() - 1;
        int y0 = nextInt() - 1;
        q.add(x0); q.add(y0); q.add(symb[x0][y0]);
        symb[x0][y0] = -1;
        
        long ans = 0;
        
        while (!q.isEmpty()) {
            
            int x = q.poll();
            int y = q.poll();
            int parent = q.poll();
            
            int child = col[get(f[x][y], p)];
            
            
            if (child == 0 || child == parent)
                continue;
            
            ans += sz[child];
            if (!wasCleared[child]) {
                wasCleared[child] = true;
                ArrayList<Cell> tmp = new ArrayList<D.Cell>();
                for (int c : list[child]) {
                    int nx = c / m;
                    int ny = c % m;
                    if (symb[nx][ny] != -1)
                        tmp.add(new Cell(nx, ny, x, y));
                }
                Collections.sort(tmp);
                for (Cell c : tmp) {
                    q.add(c.x);
                    q.add(c.y);
                    q.add(symb[c.x][c.y]);
                    symb[c.x][c.y] = -1;
                }
            }
            
            sz[parent] += sz[child];
            sz[child] = 0;
            
            if (root[parent] != -1) {
                p[root[child]] = root[parent];
                root[child] = -1;
            } else {
                root[parent] = root[child];
                col[root[child]] = parent;
                root[child] = -1;
            }
            
        }
        
        out.print(ans);
        
        
    }

    void inp() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new D().inp();
    }

    String nextToken() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return "0";
            }
        }
        return st.nextToken();
    }

    String nextString() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                eof = true;
                return "0";
            }
        }
        return st.nextToken("\n");
    }

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

}
