#include <bits/stdc++.h>
using namespace std;
template <class L>
class MinCostFlow {
 public:
  int N;
  vector<vector<L> > cap, flow, cost;
  vector<int> found;
  vector<L> dist, pi, width;
  vector<pair<int, int> > dad;
  MinCostFlow(int n)
      : N(n),
        cap(n, vector<L>(n)),
        flow(n, vector<L>(n)),
        cost(N, vector<L>(n)),
        found(n),
        dist(n),
        pi(n),
        width(n),
        dad(n) {}
  void add_edge(int from, int to, L cap_, L cost_) {
    this->cap[from][to] = cap_;
    this->cost[from][to] = cost_;
  }
  pair<L, L> get_maxflow(int s, int t) {
    L totflow = 0, totcost = 0;
    while (L amt = dijkstra(s, t)) {
      totflow += amt;
      for (int first = t; first != s; first = dad[first].first) {
        if (dad[first].second == 1) {
          flow[dad[first].first][first] += amt;
          totcost += amt * cost[dad[first].first][first];
        } else {
          flow[first][dad[first].first] -= amt;
          totcost -= amt * cost[first][dad[first].first];
        }
      }
    }
    return make_pair(totflow, totcost);
  }

 private:
  void relax(int s, int k, L cap_, L cost_, int dir) {
    L val = dist[s] + pi[s] - pi[k] + cost_;
    if (cap_ && val < dist[k]) {
      dist[k] = val;
      dad[k] = make_pair(s, dir);
      width[k] = min(cap_, width[s]);
    }
  }
  L dijkstra(int s, int t) {
    fill(found.begin(), found.end(), false);
    fill(dist.begin(), dist.end(), (1000000000));
    fill(width.begin(), width.end(), 0);
    dist[s] = 0;
    width[s] = (1000000000);
    while (s != -1) {
      int best = -1;
      found[s] = true;
      for (int k = 0; k < N; k++) {
        if (found[k]) continue;
        relax(s, k, cap[s][k] - flow[s][k], cost[s][k], 1);
        relax(s, k, flow[k][s], -cost[k][s], -1);
        if (best == -1 || dist[k] < dist[best]) best = k;
      }
      s = best;
    }
    for (int k = 0; k < N; k++) pi[k] = min(pi[k] + dist[k], (1000000000));
    return width[t];
  }
};
char cipher[(2000005)];
char answer[(2000005)];
int N, K;
int id(char first) {
  if (first >= 'a' && first <= 'z') return first - 'a';
  return 26 + first - 'A';
}
int pid(int first) {
  if (first < 26)
    return 'a' + first;
  else
    return 'A' + (first - 26);
}
int main() {
  scanf("%d %d", &N, &K);
  scanf("%s %s", cipher, answer);
  MinCostFlow<int> solver(K + K + 2);
  int source = K + K;
  int sink = K + K + 1;
  map<pair<int, int>, int> reduce;
  for (int i = 0; i < N; i++) {
    reduce[pair<int, int>(id(cipher[i]), id(answer[i]))]++;
  }
  for (int i = 0; i < K; i++) {
    solver.add_edge(source, i, 1, 0);
    solver.add_edge(K + i, sink, 1, 0);
  }
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < K; j++) {
      int c = 0;
      for (int k = 0; k < K; k++) {
        if (k != j) {
          c += reduce[pair<int, int>(i, k)];
        }
      }
      solver.add_edge(i, K + j, 1, c);
    }
  }
  printf("%d\n", N - solver.get_maxflow(source, sink).second);
  for (int i = 0; i < K; i++) {
    for (int j = K; j < K + K; j++) {
      if (solver.flow[i][j]) {
        printf("%c", pid(j - K));
        break;
      }
    }
  }
  printf("\n");
  return 0;
}
