#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline string toString(T a) {
  ostringstream os("");
  os << a;
  return os.str();
}
template <typename T>
inline long long toLong(T a) {
  long long res;
  istringstream os(a);
  os >> res;
  return res;
}
template <typename T>
inline int toInt(T a) {
  int res;
  istringstream os(a);
  os >> res;
  return res;
}
template <typename T>
inline double toDouble(T a) {
  double res;
  istringstream os(a);
  os >> res;
  return res;
}
template <typename T>
inline T SQ(T a) {
  return a * a;
}
template <typename T>
inline T GCD(T a, T b) {
  if (b == 0)
    return a;
  else
    return GCD(b, a % b);
}
template <typename T>
inline T LCM(T a, T b) {
  long long res = a * b;
  res /= GCD(a, b);
  return res;
}
template <typename T>
inline unsigned long long BIGMOD(T a, T b, T m) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0)
    return SQ(BIGMOD(a, b / 2, m)) % m;
  else
    return (a % m * BIGMOD(a, b - 1, m)) % m;
}
template <typename T>
inline vector<string> PARSE(T str) {
  vector<string> res;
  string s;
  istringstream os(str);
  while (os >> s) res.push_back(s);
  return res;
}
template <typename T>
inline unsigned long long DIST(T A, T B) {
  unsigned long long res =
      (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
  return res;
}
template <typename T>
inline long long CROSS(T A, T B, T C) {
  return (B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y);
}
template <typename T>
inline double cosAngle(T a, T b, T c) {
  double res = a * a + b * b - c * c;
  res = res / (2 * a * b);
  res = acos(res);
  return res;
}
template <typename T>
inline T POWER(T base, int po) {
  T res = 1;
  if (base == 0) return 0;
  for (int i = (0); i < (po); i++) res *= base;
  return res;
}
template <typename T>
inline bool IS_ON(T mask, T pos) {
  return mask & (1 << pos);
}
template <typename T>
inline int OFF(T mask, T pos) {
  return mask ^ (1 << pos);
}
template <typename T>
inline int ON(T mask, T pos) {
  return mask | (1 << pos);
}
template <typename T>
inline bool INSIDE_GRID(int R, int C, int ro, int clm) {
  if (R >= 0 && C >= 0 && R < ro && C < clm) return 1;
  return 0;
}
struct Edge {
  int next, src, adj, cost, cap;
} edge[20000];
int edg, first[155], source, sink, N;
void addEdge(int from, int to, int cap, int cost) {
  edge[edg].next = first[from];
  edge[edg].adj = to;
  edge[edg].src = from;
  edge[edg].cost = cost;
  edge[edg].cap = cap;
  first[from] = edg++;
  edge[edg].next = first[to];
  edge[edg].adj = from;
  edge[edg].src = to;
  edge[edg].cost = -cost;
  edge[edg].cap = 0;
  first[to] = edg++;
}
bool inq[155];
int dist[155], parent[155];
queue<int> q;
bool SPFA() {
  for (int i = (0); i < (N + 1); i++)
    dist[i] = INT_MAX / 3, inq[i] = 0, parent[i] = -1;
  inq[source] = 1;
  dist[source] = 0;
  q.push(source);
  int u, v, e;
  while (!q.empty()) {
    u = q.front();
    q.pop();
    inq[u] = 0;
    for (e = first[u]; e != -1; e = edge[e].next) {
      v = edge[e].adj;
      if (edge[e].cap && dist[v] > dist[u] + edge[e].cost) {
        parent[v] = e;
        dist[v] = dist[u] + edge[e].cost;
        if (!inq[v]) q.push(v), inq[v] = 1;
      }
    }
  }
  return dist[sink] != INT_MAX / 3;
}
int dfs(int u, int flow) {
  if (u == source) return flow;
  int ret = dfs(edge[parent[u]].src, min(edge[parent[u]].cap, flow));
  edge[parent[u] ^ 1].cap += ret;
  edge[parent[u]].cap -= ret;
  return ret;
}
pair<int, int> MCMF() {
  int flow, maxFlow = 0, minCost = 0;
  while (SPFA()) {
    flow = dfs(sink, INT_MAX / 3);
    minCost = minCost + dist[sink] * flow;
    maxFlow = maxFlow + flow;
  }
  return make_pair(maxFlow, minCost);
}
void init() {
  edg = 0;
  for (int i = (0); i < (155); i++) first[i] = -1;
}
int get(char ch) {
  if (ch >= 'a' && ch <= 'z') return ch - 'a';
  return 26 + ch - 'A';
}
char get2(int ch) {
  if (ch < 26) return 'a' + ch;
  return 'A' + ch - 26;
}
int cost[55][55];
char str1[2000006];
char str2[2000006];
char ans[55];
int main() {
  init();
  int n, m, e;
  scanf("%d%d", &n, &m);
  scanf("%s", str1);
  scanf("%s", str2);
  for (int i = (0); i < (n); i++) {
    cost[get(str1[i])][get(str2[i])]++;
  }
  source = 2 * m + 1;
  sink = 2 * m + 2;
  N = sink + 2;
  for (int i = (0); i < (m); i++) {
    addEdge(source, i, 1, 0);
    addEdge(m + i, sink, 1, 0);
    for (int j = (0); j < (m); j++) {
      addEdge(i, m + j, 1, -cost[i][j]);
    }
  }
  pair<int, int> res = MCMF();
  cout << -res.second << endl;
  for (int i = (0); i < (m); i++) {
    for (e = first[i]; e != -1; e = edge[e].next)
      if (edge[e].adj < source && edge[e].cap == 0 && edge[e ^ 1].cap > 0) {
        printf("%c", get2(edge[e].adj - m));
        break;
      }
  }
  return 0;
}
