#include <bits/stdc++.h>
using namespace std;
template <class T>
bool checkmax(T &a, T b) {
  return a < b ? a = b, true : false;
}
template <class T>
bool checkmin(T &a, T b) {
  return a > b ? a = b, true : false;
}
template <class T>
void string_reader(string s, vector<T> &vec) {
  istringstream sin(s);
  copy(istream_iterator<T>(sin), istream_iterator<T>(), back_inserter(vec));
}
const int N = 200;
const int K = 7;
const int INF = N * N * 10000;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
int matrix[N][N];
int dp[N][N][1 << K], inq[N][N][1 << K];
tuple<int, int, int> pre[N][N][1 << K];
tuple<int, int> nodes[K];
int n, m, k;
bool is_legal(int x, int y) { return 0 <= x && x < n && 0 <= y && y < m; }
char fig[N][N];
void dfs(int x, int y, int s) {
  fig[x][y] = 'X';
  int tmpx = get<0>(pre[x][y][s]), tmpy = get<1>(pre[x][y][s]),
      tmps = get<2>(pre[x][y][s]);
  if (tmpx == -1)
    return;
  else if (x == tmpx && y == tmpy) {
    dfs(x, y, s ^ tmps);
    dfs(x, y, tmps);
  } else
    dfs(tmpx, tmpy, tmps);
}
void DP() {
  int als = 1 << k;
  for (int i = 0; i < int(n); ++i)
    for (int j = 0; j < int(m); ++j) {
      fill(dp[i][j], dp[i][j] + als, INF);
      memset(pre[i][j], -1, sizeof(pre[i][j]));
      for (int kk = 0; kk < int(als); ++kk) {
        get<0>(pre[i][j][kk]) = -1;
        get<1>(pre[i][j][kk]) = -1;
        get<2>(pre[i][j][kk]) = -1;
      }
    }
  memset(inq, false, sizeof(inq));
  queue<tuple<int, int, int> > q;
  for (int i = 0; i < int(k); ++i) {
    int x = get<0>(nodes[i]), y = get<1>(nodes[i]);
    dp[x][y][1 << i] = matrix[x][y];
    inq[x][y][1 << i] = true;
    q.push(tuple<int, int, int>(x, y, 1 << i));
  }
  while (q.empty() == false) {
    auto now = q.front();
    q.pop();
    int x = get<0>(now), y = get<1>(now), s = get<2>(now);
    for (int kk = 0; kk < int(4); ++kk) {
      int tmpx = x + dx[kk];
      int tmpy = y + dy[kk];
      if (is_legal(tmpx, tmpy) == false) continue;
      if (checkmin(dp[tmpx][tmpy][s], dp[x][y][s] + matrix[tmpx][tmpy])) {
        get<0>(pre[tmpx][tmpy][s]) = x;
        get<1>(pre[tmpx][tmpy][s]) = y;
        get<2>(pre[tmpx][tmpy][s]) = s;
        if (!inq[tmpx][tmpy][s]) {
          q.push(tuple<int, int, int>(tmpx, tmpy, s));
          inq[tmpx][tmpy][s] = 1;
        }
      }
    }
    for (int kk = 0; kk < int(4); ++kk) {
      int nxts = (als - 1) ^ s;
      for (int i = nxts; i != 0; i = (i - 1) & nxts) {
        if (checkmin(dp[x][y][i | s],
                     dp[x][y][i] + dp[x][y][s] - matrix[x][y])) {
          get<0>(pre[x][y][s | i]) = x;
          get<1>(pre[x][y][s | i]) = y;
          get<2>(pre[x][y][s | i]) = s;
          if (!inq[x][y][i | s]) {
            q.push(tuple<int, int, int>(x, y, i | s));
            inq[x][y][i | s] = 1;
          }
        }
      }
    }
    inq[x][y][s] = false;
  }
  int ans = INF;
  pair<int, int> p;
  for (int i = 0; i < int(n); ++i)
    for (int j = 0; j < int(m); ++j)
      if (checkmin(ans, dp[i][j][als - 1])) p = make_pair(i, j);
  cout << ans << endl;
  dfs(p.first, p.second, als - 1);
  for (int i = 0; i < int(n); ++i)
    for (int j = 0; j < int(m); ++j) {
      cout << fig[i][j];
      if (j == m - 1) cout << endl;
    }
}
int main() {
  while (cin >> n >> m >> k) {
    for (int i = 0; i < int(n); ++i)
      for (int j = 0; j < int(m); ++j) cin >> matrix[i][j];
    memset(fig, '.', sizeof(fig));
    for (int i = 0; i < int(k); ++i) {
      cin >> get<0>(nodes[i]) >> get<1>(nodes[i]);
      get<0>(nodes[i])--;
      get<1>(nodes[i])--;
    }
    DP();
  }
  return 0;
}
