#include <bits/stdc++.h>   using namespace std;   const int INF = (int)1e9;   struct edge {     int u, v;     int flow;     int cost;     edge() {}     edge(int u, int v, int f, int c) : u(u), v(v), flow(f), cost(c) {}   };   struct MinCostMaxFlow {     int N;     vector<vector<int> > G;     vector<edge> E;     int numEdges;     vector<int> found, dad;     vector<int> dist;     MinCostMaxFlow(int N) : N(N), G(N), found(N), dist(N), dad(N), numEdges(0) {}     void addEdge(int from, int to, int capacity, int cost) {       G[from].push_back(numEdges++);       E.push_back(edge(from, to, capacity, cost));       G[to].push_back(numEdges++);       E.push_back(edge(to, from, 0, int(-1) * cost));     }     bool spfa(int s, int t) {       fill(dad.begin(), dad.end(), -1);       fill(dist.begin(), dist.end(), INF);       fill(found.begin(), found.end(), 0);       queue<int> Q;       dist[s] = 0;       Q.push(s);       found[s] = true;       while (!Q.empty()) {         int u = Q.front();         Q.pop();         if (u == t) continue;         for (int i = 0; i < G[u].size(); ++i) {           edge &pres = E[G[u][i]];           int v = pres.v;           if (pres.flow <= 0) continue;           if (dist[u] + pres.cost < dist[v]) {             dad[v] = G[u][i];             dist[v] = dist[u] + pres.cost;             if (!found[v]) Q.push(v), found[v] = true;           }         }         found[u] = false;       }       return (dad[t] != -1);     }     int dfs(int s, int t) {       int flow = INF;       for (int i = dad[t]; i != -1; i = dad[E[i].u]) {         if (E[i].flow < flow) flow = E[i].flow;       }       for (int i = dad[t]; i != -1; i = dad[E[i].u]) {         E[i].flow -= flow;         E[i ^ 1].flow += flow;       }       return flow;     }     pair<int, int> getMaxFlow(int s, int t) {       int totflow = 0;       int totcost = 0;       while (spfa(s, t)) {         int amt = dfs(s, t);         totflow += amt;         totcost += dist[t] * (int)amt;       }       return make_pair(totflow, totcost);     }   };   int main() {     int n, m;     cin >> n >> m;     vector<int> a(n);     for (int i = 0; i < n; ++i) cin >> a[i];     MinCostMaxFlow mcmf(n * 2 + m + 2);     for (int i = 0; i < n; ++i) {       for (int j = i + 1; j < n; ++j) {         mcmf.addEdge(i + 1, j + n + 1 + m, 1,                      (a[i] == a[j] ? 0 : __builtin_popcount(a[j])));       }     }     for (int i = 0; i < m; ++i) {       for (int j = 0; j < n; ++j) {         mcmf.addEdge(i + n + 1, j + n + m + 1, 1, __builtin_popcount(a[j]));       }       mcmf.addEdge(0, i + n + 1, 1, 0);     }     for (int i = 0; i < n; ++i) {       mcmf.addEdge(0, i + 1, 1, 0);       mcmf.addEdge(i + n + m + 1, n + m + n + 1, 1, 0);     }     pair<int, int> ret = mcmf.getMaxFlow(0, n + n + m + 1);     vector<int> who(n);     for (int i = 1; i <= n + m; ++i) {       for (int c : mcmf.G[i]) {         edge e = mcmf.E[c];         if (e.flow == 0 && e.v != 0) {           who[e.v - n - m - 1] = i - 1;           assert(e.u == i);         }       }     }     vector<int> last(n, -1);     vector<string> fans;     for (int i = 0; i < n; ++i) {       int f = who[i];       if (f >= n) {         stringstream ss;         ss << (char)(f - n +  a ) <<  =  << a[i] <<    ;         ss <<  print(  << (char)(f - n +  a ) <<  ) ;         string tmp;         ss >> tmp;         fans.push_back(tmp);         ss >> tmp;         fans.push_back(tmp);         last[i] = f - n;       } else {         if (a[who[i]] == a[i]) {           stringstream ss;           ss <<  print(  << (char)(last[who[i]] +  a ) <<  ) ;           string tmp;           ss >> tmp;           fans.push_back(tmp);         } else {           stringstream ss;           ss << (char)(last[who[i]] +  a ) <<  =  << a[i] <<    ;           ss <<  print(  << (char)(last[who[i]] +  a ) <<  ) ;           string tmp;           ss >> tmp;           fans.push_back(tmp);           ss >> tmp;           fans.push_back(tmp);         }         last[i] = last[who[i]];       }     }     cout << fans.size() <<     << ret.second <<   n ;     for (string t : fans) cout << t <<   n ;     return 0;   }