#include <bits/stdc++.h>
using namespace std;
struct node {
  int r, c, dist;
  node() {}
  node(int _r, int _c, int _dist) : r(_r), c(_c), dist(_dist) {}
  bool operator<(node X) const { return dist > X.dist; }
};
int n, m, r[7], c[7], M[100][100], id[100][100];
int dist[200][200], px[200][200], py[200][200];
int memo[100][100][(1 << 7)], choosex[100][100][(1 << 7)],
    choosey[100][100][(1 << 7)], choosem[100][100][(1 << 7)];
int solve(int x, int y, int mask) {
  if (mask == 0) return 0;
  int &ret = memo[x][y][mask];
  if (ret == -1) {
    if (__builtin_popcount(mask) == 1) {
      int v = __builtin_ctz(mask);
      ret = dist[x * m + y][r[v] * m + c[v]];
    } else {
      ret = 200000;
      for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
          for (int mask2 = (mask - 1) & mask; mask2 > 0;
               mask2 = (mask2 - 1) & mask) {
            int m1 = mask, m2 = mask2;
            if (id[i][j] != -1) {
              m1 &= ~(1 << id[i][j]);
              m2 &= ~(1 << id[i][j]);
            }
            int aux = dist[x * m + y][i * m + j] + solve(i, j, m2) +
                      solve(i, j, m1 ^ m2);
            if (aux < ret) {
              ret = aux;
              choosex[x][y][mask] = i;
              choosey[x][y][mask] = j;
              choosem[x][y][mask] = mask2;
            }
          }
    }
  }
  return ret;
}
char sol[100][101];
void search(int x, int y, int mask) {
  sol[x][y] = 'X';
  if (mask == 0) return;
  int x2, y2;
  if (__builtin_popcount(mask) == 1) {
    int v = __builtin_ctz(mask);
    x2 = r[v];
    y2 = c[v];
  } else {
    x2 = choosex[x][y][mask];
    y2 = choosey[x][y][mask];
    int mask2 = choosem[x][y][mask];
    if (id[x2][y2] != -1) {
      mask &= ~(1 << id[x2][y2]);
      mask2 &= ~(1 << id[x2][y2]);
    }
    search(x2, y2, mask2);
    search(x2, y2, mask ^ mask2);
  }
  while (x2 != x || y2 != y) {
    sol[x2][y2] = 'X';
    int x3 = px[x * m + y][x2 * m + y2], y3 = py[x * m + y][x2 * m + y2];
    x2 = x3;
    y2 = y3;
  }
}
int main() {
  int k;
  scanf("%d %d %d", &n, &m, &k);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) scanf("%d", &M[i][j]);
  int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};
  int N = n * m;
  for (int i = 0; i < N; ++i)
    for (int j = 0; j < N; ++j) dist[i][j] = 200001;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      priority_queue<node> Q;
      Q.push(node(i, j, 0));
      dist[i * m + j][i * m + j] = 0;
      while (!Q.empty()) {
        node aux = Q.top();
        Q.pop();
        if (aux.dist > dist[i * m + j][aux.r * m + aux.c]) continue;
        for (int d = 0; d < 4; ++d) {
          int r2 = aux.r + dr[d];
          int c2 = aux.c + dc[d];
          if (r2 >= 0 && r2 < n && c2 >= 0 && c2 < m &&
              aux.dist + M[r2][c2] < dist[i * m + j][r2 * m + c2]) {
            Q.push(node(r2, c2, aux.dist + M[r2][c2]));
            dist[i * m + j][r2 * m + c2] = aux.dist + M[r2][c2];
            px[i * m + j][r2 * m + c2] = aux.r;
            py[i * m + j][r2 * m + c2] = aux.c;
          }
        }
      }
    }
  }
  memset(id, -1, sizeof id);
  for (int i = 0; i < k; ++i) {
    scanf("%d %d", &r[i], &c[i]);
    --r[i];
    --c[i];
    id[r[i]][c[i]] = i;
  }
  memset(memo, -1, sizeof memo);
  printf("%d\n", M[r[0]][c[0]] + solve(r[0], c[0], (1 << k) - 2));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) sol[i][j] = '.';
  search(r[0], c[0], (1 << k) - 2);
  for (int i = 0; i < n; ++i) puts(sol[i]);
  return 0;
}
