#include <bits/stdc++.h>
using namespace std;
const int Nmax = 205, Kmax = 105, Pmax = 7, Inf = 0x3f3f3f3f;
const int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0, 1};
int A[Kmax][Kmax];
char B[Kmax][Kmax];
vector<int> G[Nmax];
int N, M, P;
int cost[Nmax];
int dist[Nmax][Nmax], from[Nmax][Nmax];
int dp[1 << Pmax][Nmax], pprev[1 << Pmax][Nmax];
bool typer[1 << Pmax][Nmax];
vector<int> specials;
int posSp[Nmax];
bool inQueue[Nmax];
inline int getkey(int x, int y) { return (x - 1) * M + y; }
inline pair<int, int> getcell(int x) {
  return make_pair((x - 1) / M + 1, (x - 1) % M + 1);
}
inline void mark(int x) {
  pair<int, int> cell = getcell(x);
  B[cell.first][cell.second] = 'X';
}
void getDist(int dist[], int from[], int S) {
  from[S] = -1;
  memset(dist, Inf, sizeof(int) * Nmax);
  dist[S] = cost[S];
  queue<int> Q;
  Q.push(S);
  while (!Q.empty()) {
    int node = Q.front();
    Q.pop();
    inQueue[node] = false;
    for (int p : G[node]) {
      if (dist[p] > dist[node] + cost[p]) {
        dist[p] = dist[node] + cost[p];
        from[p] = node;
        if (!inQueue[p]) {
          Q.push(p);
          inQueue[p] = true;
        }
      }
    }
  }
}
int getAns(int conf, int node) {
  int &ans = dp[conf][node];
  if (ans != -1) return ans;
  if (conf == 0) return ans = cost[node];
  if (posSp[node] != 0) {
    int x = posSp[node] - 1;
    if (conf == (1 << x)) return ans = cost[node];
  }
  ans = Inf;
  for (int nconf = (conf - 1) & conf; nconf > 0; nconf = (nconf - 1) & conf) {
    int ccost = getAns(nconf, node) + getAns(conf ^ nconf, node) - cost[node];
    if (ccost < ans) {
      ans = ccost;
      typer[conf][node] = false;
      pprev[conf][node] = nconf;
    }
  }
  for (int i = 1; i <= N * M; ++i) {
    if (i == node) continue;
    int ccost = getAns(conf, i) + dist[i][node] - cost[i];
    if (ccost < ans) {
      ans = ccost;
      typer[conf][node] = true;
      pprev[conf][node] = i;
    }
  }
  return ans;
}
void fillMatrix(int conf, int node) {
  mark(node);
  if ((posSp[node] != 0 && conf == (1 << posSp[node] - 1)) || conf == 0) return;
  if (typer[conf][node]) {
    int x = pprev[conf][node];
    for (int i = node; i != x; i = from[x][i]) mark(i);
    fillMatrix(conf, x);
  } else {
    int x = pprev[conf][node];
    fillMatrix(x, node);
    fillMatrix(conf ^ x, node);
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> N >> M >> P;
  for (int i = 1; i <= N; ++i)
    for (int j = 1; j <= M; ++j) cin >> A[i][j];
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= M; ++j) {
      int k1 = getkey(i, j);
      cost[k1] = A[i][j];
      for (int k = 0; k < 4; ++k) {
        int nx = i + dx[k], ny = j + dy[k];
        if (nx < 1 || nx > N || ny < 1 || ny > M) continue;
        int k2 = getkey(nx, ny);
        G[k1].push_back(k2);
      }
    }
  }
  for (int i = 1; i <= N * M; ++i) {
    getDist(dist[i], from[i], i);
  }
  for (int i = 0; i < P; ++i) {
    int x, y;
    cin >> x >> y;
    int k = getkey(x, y);
    posSp[k] = i + 1;
    specials.push_back(k);
  }
  memset(dp, -1, sizeof dp);
  int ans = Inf, conf = (1 << P) - 1, node = 0;
  for (int i = 1; i <= N * M; ++i) {
    int cost = getAns(conf, i);
    if (cost < ans) {
      ans = cost;
      node = i;
    }
  }
  for (int i = 1; i <= N; ++i) {
    for (int j = 1; j <= M; ++j) {
      B[i][j] = '.';
    }
  }
  fillMatrix(conf, node);
  cout << ans << '\n';
  for (int i = 1; i <= N; ++i) cout << (B[i] + 1) << '\n';
}
