#include <bits/stdc++.h>   using namespace std;   template <typename flow_t = int, typename cost_t = int>   struct mcSFlow {     struct Edge {       cost_t c;       flow_t f;       int to, rev;       Edge(int _to, cost_t _c, flow_t _f, int _rev)           : c(_c), f(_f), to(_to), rev(_rev) {}     };     const cost_t INFCOST = numeric_limits<cost_t>::max() / 2;     const cost_t INFFLOW = numeric_limits<flow_t>::max() / 2;     cost_t epsilon;     int N, S, T;     vector<vector<Edge> > G;     vector<unsigned int> isEnqueued, state;     mcSFlow(int _N, int _S, int _T) : epsilon(0), N(_N), S(_S), T(_T), G(_N) {}     void add_edge(int a, int b, cost_t cost, flow_t cap) {       if (a == b) {         assert(cost >= 0);         return;       }       cost *= N;       epsilon = max(epsilon, abs(cost));       assert(a >= 0 && a < N && b >= 0 && b < N);       G[a].emplace_back(b, cost, cap, G[b].size());       G[b].emplace_back(a, -cost, 0, G[a].size() - 1);     }     flow_t calc_max_flow() {       vector<flow_t> dist(N), state(N);       vector<Edge *> path(N);       auto cmp = [](Edge *a, Edge *b) { return a->f < b->f; };       flow_t addFlow, retflow = 0;       ;       do {         fill(dist.begin(), dist.end(), -1);         dist[S] = 0;         auto head = state.begin(), tail = state.begin();         for (*tail++ = S; head != tail; ++head) {           for (Edge const &e : G[*head]) {             if (e.f && dist[e.to] == -1) {               dist[e.to] = dist[*head] + 1;               *tail++ = e.to;             }           }         }         addFlow = 0;         fill(state.begin(), state.end(), 0);         auto top = path.begin();         Edge dummy(S, 0, INFFLOW, -1);         *top++ = &dummy;         while (top != path.begin()) {           int n = (*prev(top))->to;           if (n == T) {             auto next_top = min_element(path.begin(), top, cmp);             flow_t flow = (*next_top)->f;             while (--top != path.begin()) {               Edge &e = **top, &f = G[e.to][e.rev];               e.f -= flow;               f.f += flow;             }             addFlow = 1;             retflow += flow;             top = next_top;             continue;           }           for (flow_t &i = state[n], i_max = G[n].size(), need = dist[n] + 1;;                ++i) {             if (i == i_max) {               dist[n] = -1;               --top;               break;             }             if (dist[G[n][i].to] == need && G[n][i].f) {               *top++ = &G[n][i];               break;             }           }         }       } while (addFlow);       return retflow;     }     vector<flow_t> excess;     vector<cost_t> h;     void push(Edge &e, flow_t amt) {       if (e.f < amt) amt = e.f;       e.f -= amt;       excess[e.to] += amt;       G[e.to][e.rev].f += amt;       excess[G[e.to][e.rev].to] -= amt;     }     void relabel(int vertex) {       cost_t newHeight = -INFCOST;       for (unsigned int i = 0; i < G[vertex].size(); ++i) {         Edge const &e = G[vertex][i];         if (e.f && newHeight < h[e.to] - e.c) {           newHeight = h[e.to] - e.c;           state[vertex] = i;         }       }       h[vertex] = newHeight - epsilon;     }     const int scale = 2;     pair<flow_t, cost_t> minCostFlow() {       cost_t retCost = 0;       for (int i = 0; i < N; ++i) {         for (Edge &e : G[i]) {           retCost += e.c * (e.f);         }       }       flow_t retFlow = calc_max_flow();       excess.resize(N);       h.resize(N);       queue<int> q;       isEnqueued.assign(N, 0);       state.assign(N, 0);       for (; epsilon; epsilon >>= scale) {         fill(state.begin(), state.end(), 0);         for (int i = 0; i < N; ++i)           for (auto &e : G[i])             if (h[i] + e.c - h[e.to] < 0 && e.f) push(e, e.f);         for (int i = 0; i < N; ++i) {           if (excess[i] > 0) {             q.push(i);             isEnqueued[i] = 1;           }         }         while (!q.empty()) {           int cur = q.front();           q.pop();           isEnqueued[cur] = 0;           while (excess[cur] > 0) {             if (state[cur] == G[cur].size()) {               relabel(cur);             }             for (unsigned int &i = state[cur], max_i = G[cur].size(); i < max_i;                  ++i) {               Edge &e = G[cur][i];               if (h[cur] + e.c - h[e.to] < 0) {                 push(e, excess[cur]);                 if (excess[e.to] > 0 && isEnqueued[e.to] == 0) {                   q.push(e.to);                   isEnqueued[e.to] = 1;                 }                 if (excess[cur] == 0) break;               }             }           }         }         if (epsilon > 1 && epsilon >> scale == 0) {           epsilon = 1 << scale;         }       }       for (int i = 0; i < N; ++i) {         for (Edge &e : G[i]) {           retCost -= e.c * (e.f);         }       }       return make_pair(retFlow, retCost / 2 / N);     }     flow_t getFlow(Edge const &e) { return G[e.to][e.rev].f; }   };   const int N = 260, M = 30, inf = 1e5 + 42;   int a[N];   char var[N];   int val[M];   int main() {     ios_base::sync_with_stdio(false);     cin.tie(NULL);     int n, m;     cin >> n >> m;     int act_source = 0, source = 1, sink = 2 * n + 2;     mcSFlow<long long, long long> mf(sink + 1, act_source, sink);     mf.add_edge(act_source, source, 0, m);     mf.add_edge(source, sink, 0, inf);     for (int i = 1; i <= n; ++i) {       cin >> a[i];       mf.add_edge(source, 2 * i, __builtin_popcount(a[i]), inf);       mf.add_edge(2 * i, 2 * i + 1, -inf, 1);       mf.add_edge(2 * i + 1, sink, 0, inf);     }     for (int i = 1; i <= n; ++i) {       for (int j = i + 1; j <= n; ++j) {         mf.add_edge(2 * i + 1, 2 * j,                     (a[i] == a[j]) ? 0 : __builtin_popcount(a[j]), inf);       }     }     auto ans = mf.minCostFlow();     assert(ans.first == m);     ans.second += n * inf;     char nxt_var =  a ;     for (int i = 1; i <= n; ++i) {       if (!var[i]) {         var[i] = nxt_var++;       }       for (auto &e : mf.G[2 * i + 1]) {         if (mf.getFlow(e) == 1 and e.to != sink) {           var[e.to / 2] = var[i];           break;         }       }     }     vector<string> events;     for (int i = 1; i <= n; ++i) {       if (val[var[i] -  a ] != a[i]) {         val[var[i] -  a ] = a[i];         events.push_back(var[i] + string( = ) + to_string(a[i]));       }       events.push_back(string( print( ) + var[i] + string( ) ));     }     cout << events.size() <<     << ans.second <<   n ;     for (auto &s : events) {       cout << s <<   n ;     }   }