using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Aleksa1
{
    class Program
    {
        static List<List<int>> allPaths = new List<List<int>>();

        static void Main(string[] args)
        {
            var dimenzijeGrada = Console.ReadLine().Split();
            var rows = int.Parse(dimenzijeGrada[0]);
            var cols = int.Parse(dimenzijeGrada[1]);

            var doha = new List<List<int>>();
            for (int i = 0; i < rows; i++)
            {
                var navijaciUlaz = Console.ReadLine().Split();
                doha.Add(navijaciUlaz.Select(x => int.Parse(x)).ToList());
            }

            var blokade = new List<(int, int)>();
            int q = int.Parse(Console.ReadLine());
            for (int i = 0; i < q; i++)
            {
                var blokadaUlaz = Console.ReadLine().Split();
                blokade.Add((int.Parse(blokadaUlaz[0]), int.Parse(blokadaUlaz[1])));
            }

            findPaths(doha, rows, cols, blokade);

            int minBrojNavijaca = -1;
            for (int i = 0; i < allPaths.Count; i++)
            {
                var path = allPaths[i];
                var brojNavijaca = path.Sum();
                if (minBrojNavijaca == -1 || minBrojNavijaca > brojNavijaca)
                {
                    minBrojNavijaca = brojNavijaca;
                }
            }

            Console.WriteLine(minBrojNavijaca);
        }

        static void findPaths(List<List<int>> city, int m, int n, List<(int, int)> blocks)
        {
            var path = new List<int>();
            for (int i = 0; i < m + n - 1; i++)
            {
                path.Add(0);
            }
            findPathsUtil(city, m, n, 0, 0, path, 0, blocks);
        }

        static void findPathsUtil(List<List<int>> city, int m, int n, int i, int j, List<int> path, int index, List<(int, int)> blocks)
        {
            if (blocks.Contains((i, j)))
            {
                return;
            }
            // If we reach the bottom of city, we can only move right
            if (i == m - 1)
            {
                for (int k = j; k < n; k++)
                {
                    path[index + k - j] = city[i][k];
                }

                // If we hit this block, it means one path is completed. Add it to paths list
                var newPath = new List<int>();
                newPath.Add(path[0]);
                for (int z = 1; z < path.Count - 1; z++)
                {
                    newPath.Add(path[z]);
                }
                newPath.Add(path[path.Count - 1]);
                allPaths.Add(newPath);
                return;
            }

            // If we reach to the right most corner, we can only move down
            if (j == n - 1)
            {
                for (int k = i; k < m; k++)
                {
                    path[index + k - i] = city[k][j];
                }

                // If we hit this block, it means one path is completed. Add it to paths list
                var newPath = new List<int>();
                var newPathInd = new List<(int, int)>();
                newPath.Add(path[0]);
                for (int z = 1; z < path.Count - 1; z++)
                {
                    newPath.Add(path[z]);
                }
                newPath.Add(path[path.Count - 1]);
                allPaths.Add(newPath);
                return;
            }

            // Add current element to the path list
            path[index] = city[i][j];

            // Move down in y direction and call findPathsUtil recursively
            findPathsUtil(city, m, n, i + 1, j, path, index + 1, blocks);

            // Move down in y direction and call findPathsUtil recursively
            findPathsUtil(city, m, n, i, j + 1, path, index + 1, blocks);
        }
    }
}