#include <bits/stdc++.h>
using namespace std;
int t;
int n, m, k;
const int N = 110;
int a[N][N];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
vector<int> e[N * N], val[N * N];
int dp[N * N][1 << 7];
vector<int> nodes[N * N][1 << 7];
bool u[N * N], ans[N * N];
struct ele {
  int cost;
  vector<int> node;
  int vex;
};
bool operator<(ele x, ele y) { return x.cost > y.cost; }
priority_queue<ele> que;
void vclear(int i, int j) {
  int t1 = (i - 1) * m + j;
  e[t1].clear();
  val[t1].clear();
}
void addedge(int i, int j, int tx, int ty, int w) {
  int t1 = (i - 1) * m + j;
  int t2 = (tx - 1) * m + ty;
  e[t1].push_back(t2);
  val[t1].push_back(w);
}
vector<int> uni(vector<int> a, vector<int> b) {
  vector<int> ret;
  for (auto v : a) ret.push_back(v);
  for (auto v : b) ret.push_back(v);
  return ret;
}
void dijkstra(int s) {
  memset(u, 0, sizeof(u));
  while (!que.empty()) {
    ele tmp = que.top();
    que.pop();
    int tp = tmp.vex;
    if (u[tp] == 1) continue;
    u[tp] = 1;
    dp[tp][s] = tmp.cost;
    nodes[tp][s] = tmp.node;
    for (int i = (0); i < (e[tp].size()); i++) {
      int v = e[tp][i];
      if (u[v] == 1) continue;
      ele tt;
      tt.vex = v;
      tt.cost = tmp.cost + val[tp][i];
      tt.node = tmp.node;
      tt.node.push_back(v);
      que.push(tt);
    }
  }
}
int main() {
  while (cin >> n >> m >> k) {
    int nn = n * m;
    for (int i = (1); i < (n + 1); i++)
      for (int j = (1); j < (m + 1); j++) {
        cin >> a[i][j];
        vclear(i, j);
      }
    for (int i = (1); i < (n + 1); i++)
      for (int j = (1); j < (m + 1); j++) {
        for (int _ = (0); _ < (4); _++) {
          int tx = i + dx[_];
          int ty = j + dy[_];
          if (tx < 1 || tx > n || ty < 1 || ty > m) continue;
          addedge(i, j, tx, ty, a[tx][ty]);
        }
      }
    memset(dp, 0x3f, sizeof(dp));
    int tpos;
    for (int i = (1); i < (k + 1); i++) {
      int tx, ty;
      cin >> tx >> ty;
      int pos = (tx - 1) * m + ty;
      tpos = pos;
      dp[pos][1 << (i - 1)] = a[tx][ty];
      nodes[pos][1 << (i - 1)].clear();
      nodes[pos][1 << (i - 1)].push_back(pos);
    }
    for (int s = (1); s < (1 << k); s++) {
      for (int ii = (1); ii < (n + 1); ii++)
        for (int jj = (1); jj < (m + 1); jj++) {
          int i = (ii - 1) * m + jj;
          for (int sub = s & (s - 1); sub; sub = s & (sub - 1)) {
            if (dp[i][s] > dp[i][sub] + dp[i][s ^ sub] - a[ii][jj]) {
              dp[i][s] = dp[i][sub] + dp[i][s ^ sub] - a[ii][jj];
              nodes[i][s] = uni(nodes[i][sub], nodes[i][s ^ sub]);
            }
          }
          if (dp[i][s] != -1) {
            ele tmp;
            tmp.cost = dp[i][s];
            tmp.node = nodes[i][s];
            tmp.vex = i;
            que.push(tmp);
          }
        }
      dijkstra(s);
    }
    cout << dp[tpos][(1 << k) - 1] << '\n';
    memset(ans, 0, sizeof(ans));
    for (auto v : nodes[tpos][(1 << k) - 1]) ans[v] = 1;
    int tt = 0;
    for (int i = (1); i < (n + 1); i++) {
      for (int j = (1); j < (m + 1); j++) {
        int pos = (i - 1) * m + j;
        if (ans[pos] == 1)
          cout << 'X';
        else
          cout << '.';
      }
      cout << '\n';
    }
  }
  return 0;
}
