#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 200, MAX_M = 3000, MAX_K = 60;
const long long MAX_C = 1000000000000000;
struct Edge {
  int from, to, app;
  long long weight;
  long long cap, flow;
  bool inv;
  Edge(int a, int b, int w, int c, bool t) {
    from = a;
    to = b;
    weight = w;
    cap = c;
    flow = 0;
    inv = t;
  }
  int rcap() {
    if (inv) return flow;
    return cap - flow;
  }
};
long long used[MAX_N], edge_to[MAX_N], matching[MAX_K];
vector<long long> graph[MAX_N], dist(MAX_N), p(MAX_N);
vector<Edge> edges;
int n, m, k;
long long sumpaths = 0;
int cc = 0;
void addEdge(int from, int to, int w) {
  edges.emplace_back(Edge(from, to, w, 1, false));
  graph[from].emplace_back(edges.size() - 1);
  edges.emplace_back(Edge(to, from, -w, 0, true));
  graph[to].emplace_back(edges.size() - 1);
  edges[edges.size() - 1].app = edges.size() - 2;
  edges[edges.size() - 2].app = edges.size() - 1;
}
void bfs(int v) {
  queue<int> q;
  used[v] = cc;
  q.push(v);
  while (!q.empty()) {
    v = q.front();
    q.pop();
    for (int e : graph[v]) {
      int to = edges[e].to;
      if (used[to] != cc && edges[e].flow != 0 && !edges[e].inv) {
        edge_to[to] = e;
        used[to] = cc;
        q.push(to);
      }
    }
  }
}
void potent(int v) {
  fill(p.begin(), p.end(), MAX_C);
  p[v] = 0;
  for (int i = 0; i < n - 1; ++i) {
    for (Edge e : edges) {
      if (!e.inv && p[e.from] < MAX_C) {
        p[e.to] = min(p[e.to], p[e.from] + e.weight);
      }
    }
  }
}
void dijkstra(int v) {
  fill(dist.begin(), dist.end(), MAX_C);
  dist[v] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      pq;
  pq.push(make_pair(0, v));
  while (!pq.empty()) {
    int u = pq.top().second;
    pq.pop();
    for (int e : graph[u]) {
      Edge edge = edges[e];
      if (edge.rcap() != 0 &&
          dist[edge.to] > dist[u] + edge.weight + p[edge.to] - p[edge.from]) {
        dist[edge.to] = dist[u] + edge.weight + p[edge.to] - p[edge.from];
        pq.push(make_pair(dist[edge.to], edge.to));
        used[edge.to] = cc;
        edge_to[edge.to] = e;
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    p[i] = dist[i];
  }
}
int blockFlow(int from, int to) {
  long long bFlow = MAX_C;
  for (int v = to; v != from; v = edges[edge_to[v]].from) {
    if (bFlow > edges[edge_to[v]].rcap()) {
      bFlow = edges[edge_to[v]].rcap();
    }
  }
  return bFlow;
}
void findFlow(int from, int to) {
  long long pFlow = MAX_C;
  vector<int> path;
  for (int v = to; v != from; v = edges[edge_to[v]].from) {
    if (v != to && edges[edge_to[v]].from != from) {
      matching[edges[edge_to[v]].from] = v - k;
    }
    if (pFlow > edges[edge_to[v]].flow) {
      pFlow = edges[edge_to[v]].flow;
    }
  }
  for (int v = to; v != from; v = edges[edge_to[v]].from) {
    edges[edge_to[v]].flow -= pFlow;
    sumpaths -= edges[edge_to[v]].weight;
    long long su = sumpaths;
  }
}
void addFlow(int from, int to, int flow) {
  for (int v = to; v != from; v = edges[edge_to[v]].from) {
    if (!edges[edge_to[v]].inv) {
      edges[edge_to[v]].flow += flow;
      edges[edges[edge_to[v]].app].flow += flow;
    } else {
      edges[edge_to[v]].flow -= flow;
      edges[edges[edge_to[v]].app].flow -= flow;
    }
  }
}
long long maxFlow(int from, int to) {
  long long flow = 0;
  int d_flow = 1;
  ++cc;
  potent(2 * k);
  dijkstra(from);
  while (used[to] == cc) {
    d_flow = blockFlow(from, to);
    addFlow(from, to, d_flow);
    flow += d_flow;
    ++cc;
    dijkstra(from);
  }
  return flow;
}
void buildDecomposition(int from, int to) {
  ++cc;
  bfs(from);
  while (used[to] == cc) {
    findFlow(from, to);
    ++cc;
    bfs(from);
  }
}
int main() {
  int l;
  cin >> l >> k;
  n = 2 * k + 2;
  m = k * k + 2 * k;
  int counts[k][k];
  for (int i = 0; i < k; ++i) {
    for (int j = 0; j < k; ++j) {
      counts[i][j] = 0;
    }
  }
  string s1, s2;
  cin >> s1;
  cin >> s2;
  int a, b;
  for (int i = 0; i < l; ++i) {
    if (s1[i] >= 'a') {
      a = s1[i] - 'a';
    } else {
      a = s1[i] - 'A' + 26;
    }
    if (s2[i] >= 'a') {
      b = s2[i] - 'a';
    } else {
      b = s2[i] - 'A' + 26;
    }
    ++counts[a][b];
  }
  for (int i = 0; i < k; ++i) {
    for (int j = 0; j < k; ++j) {
      addEdge(i, k + j, -counts[i][j]);
    }
  }
  for (int i = 0; i < k; ++i) {
    addEdge(2 * k, i, 0);
    addEdge(k + i, 2 * k + 1, 0);
  }
  long long f = maxFlow(2 * k, 2 * k + 1);
  buildDecomposition(2 * k, 2 * k + 1);
  cout << sumpaths << '\n';
  for (int i = 0; i < k; ++i) {
    if (matching[i] < 26) {
      cout << static_cast<char>(matching[i] + 'a');
    } else {
      cout << static_cast<char>(matching[i] - 26 + 'A');
    }
  }
  return 0;
}
