#include <bits/stdc++.h>
using namespace std;
const int oo = (1 << 28);
const int N = (1 << 8) + 10;
const int M = 227 * 2;
int dp[N][M], w[M], dis[M][M], node[8];
int distrace[M][M], dptrace[N][M];
int cover[M][M];
int n, m, sum, nodenum;
int abs(int x) { return x < 0 ? -x : x; }
bool isconnect(int a, int b) {
  int ax = a % m, ay = a / m;
  int bx = b % m, by = b / m;
  if (abs(ax - bx) + abs(ay - by) == 1) return true;
  return false;
}
void floyd() {
  fill(dis[0], dis[0] + M * M, oo);
  for (int i = 0; i < sum; i++) {
    for (int j = 0; j < sum; j++) {
      if (i == j)
        dis[i][j] = 0;
      else if (isconnect(i, j))
        dis[i][j] = w[j];
    }
  }
  for (int k = 0; k < sum; k++)
    for (int i = 0; i < sum; i++)
      for (int j = 0; j < sum; j++) {
        if (dis[i][j] > dis[i][k] + dis[k][j]) {
          dis[i][j] = dis[i][k] + dis[k][j];
          distrace[i][j] = k;
        }
      }
  for (int i = 0; i < sum; i++)
    for (int j = 0; j < sum; j++) dis[i][j] += w[i];
}
void setpath(int u, int v) {
  cover[u / m][u % m] = cover[v / m][v % m] = 1;
  if (distrace[u][v] == -1) return;
  int pre = distrace[u][v];
  setpath(u, pre);
  setpath(pre, v);
}
void getpath(int set, int cur) {
  if (dptrace[set][cur] == -1) return;
  int pre = dptrace[set][cur];
  if (!(set & (set - 1))) {
    setpath(cur, pre - (1 << nodenum));
    return;
  }
  if (pre >= (1 << nodenum)) {
    setpath(pre - (1 << nodenum), cur);
    getpath(set, pre - (1 << nodenum));
  } else {
    getpath(set ^ pre, cur);
    getpath(pre, cur);
  }
}
int main() {
  while (scanf("%d %d %d", &n, &m, &nodenum) == 3) {
    int x, y;
    sum = n * m;
    memset(cover, 0, sizeof(cover));
    memset(dptrace, -1, sizeof(dptrace));
    memset(distrace, -1, sizeof(distrace));
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        scanf("%d", &w[i * m + j]);
      }
    }
    for (int i = 0; i < nodenum; i++) {
      scanf("%d %d", &y, &x);
      y--, x--;
      node[i] = y * m + x;
    }
    floyd();
    fill(dp[0], dp[0] + N * M, oo);
    for (int i = 0; i < sum; i++) {
      for (int j = 0; j < nodenum; j++) {
        dp[1 << j][i] = dis[i][node[j]];
        dptrace[(1 << j)][i] = node[j] + (1 << nodenum);
      }
    }
    for (int i = 0; i < (1 << nodenum); i++) {
      for (int j = 0; j < sum; j++) {
        for (int k = i & (i - 1); k; k = (k - 1) & i) {
          int tmp = dp[i ^ k][j] + dp[k][j] - w[j];
          if (dp[i][j] > tmp) {
            dp[i][j] = tmp;
            dptrace[i][j] = k;
          }
        }
      }
      for (int j = 0; j < sum; j++) {
        for (int k = 0; k < sum; k++) {
          int tmp = dp[i][k] + dis[k][j] - w[k];
          if (dp[i][j] > tmp) {
            dp[i][j] = tmp;
            dptrace[i][j] = k + (1 << nodenum);
          }
        }
      }
    }
    int ans = oo, ind = -1;
    for (int i = 0; i < sum; i++) {
      if (ans > dp[(1 << nodenum) - 1][i]) {
        ans = dp[(1 << nodenum) - 1][i];
        ind = i;
      }
    }
    printf("%d\n", ans);
    getpath((1 << nodenum) - 1, ind);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        printf("%c", cover[i][j] ? 'X' : '.');
      }
      printf("\n");
    }
  }
  return 0;
}
