// READ A SPARSE POINTS MATRIX
// READ A GRID
// EVALUATE FITNESS
#include <stdio.h>
#include <stdlib.h>

// a C-like definition of the fitness function
//
// assume the array points is filled for all pairs in 1..N by 1..N.
// All elements not explicitly given a value by the problem are set to zero.
//
// NOTE: this a specification for the function and may be 
// implemented more efficiently if desired.

// given a grid to score stored in num and a pairs scoring list
// stored in points compute the score of the grid.

int getPoints(bool **used, int **num, int **points, int X, int Y, int xy, int x, int y)
{
    // in range
    if ((x<0) || (x>=X) || (y<0) || (y>=Y)) {
        return 0;
    }        
    else {
        // not previously counted pair
        if (!used[xy][num[x][y]]) {
            if (points[xy][num[x][y]]) {
                used[xy][num[x][y]] = true;
                return points[xy][num[x][y]]; 
            }
        }    
        return 0;
    }
}


int scoreGrid(int **num, int **points, int X, int Y, int N)
{
    int score;
    bool **used;
    int numUsed;

    // local function that checks for bounds and return the right number
    // of points
    // clear the used flags
    used = new bool *[N+1];
    for (int i=0; i<=N; i++) {
        used[i] = new bool [N+1];
        for (int j=0; j<=N; j++) {
            used[i][j] = false;
        }
    }

    score = 0;
    for (int x=0; x<X; x++) {
        for (int y=0; y<Y; y++) {

            // score the pairs in the neighborhood of (x, y)
            score += getPoints(used, num, points, X, Y, num[x][y], x+1, y-1);
            score += getPoints(used, num, points, X, Y, num[x][y], x+1, y);   
            score += getPoints(used, num, points, X, Y, num[x][y], x+1, y+1); 
            score += getPoints(used, num, points, X, Y, num[x][y], x,   y-1); 
            score += getPoints(used, num, points, X, Y, num[x][y], x,   y+1); 
            score += getPoints(used, num, points, X, Y, num[x][y], x-1, y-1); 
            score += getPoints(used, num, points, X, Y, num[x][y], x-1, y);   
            score += getPoints(used, num, points, X, Y, num[x][y], x-1, y+1); 
        }
    }

    // note we ignore matches for zero
    numUsed = 0;
    for (int i=1; i<=N; i++) {
        for (int j=1; j<=N; j++) {
            if (used[i][j]) numUsed++;
        }
    }

    return score;
}    


void readPoints(int **&points, int &nn)
{
    int xx, yy;
    int numPoints;

    // allowable numbers from 0 to n-1
    scanf("%d", &xx); // ignored
    scanf("%d", &yy); // ignored
    scanf("%d", &nn);

    // create and zero matrix
    points = new int *[nn];
    for (int i=0; i<nn; i++) {
        points[i] = new int [nn];
        for (int j=0; j<nn; j++) {
            points[i][j] = 0;
        }
    }

    // read in point values
    while (true) {
        int i, j;

        scanf("%d", &i);
        if (i<0) break;
        scanf("%d", &j);
        scanf("%d", &points[i][j]);
    }
}


void readGrid(int **&num, int &xx, int &yy, int &nn)
{
    scanf("%d", &xx);
    scanf("%d", &yy);
    scanf("%d", &nn);

    num = new int *[xx];
    for (int i=0; i<xx; i++) {
        num[i] = new int [yy];
        for (int j=0; j<yy; j++) {
            scanf("%d", &num[i][j]);
        }
    }
}


int main()
{
    int xx, yy, nn, nn2;
    int **points;
    int **num;
    int score;

    readPoints(points, nn);
    readGrid(num, xx, yy, nn2);
    if (nn!=nn2) printf("ERROR: read in points for grid values 1..%d then read grid with values 1..%d\n", nn, nn2);
    printf("%3d %3d %3d: %d\n", xx, yy, nn, scoreGrid(num, points, xx, yy, nn));
}
