#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-9;
const double oo = 1e9;
template <class Flow, class Cost>
struct MinCostFlow {
  struct Edge {
    int v, inv;
    Flow c, f;
    Cost w;
    Edge(){};
    Edge(int v, Flow c, Cost w, int inv) : v(v), inv(inv), c(c), f(0), w(w) {}
  };
  int n, s, t;
  vector<vector<Edge> > e;
  vector<Cost> d;
  vector<int> parent, pEdge, state;
  deque<int> q;
  MinCostFlow(int n, int s = 1, int t = 2)
      : n(n),
        s(s),
        t(t),
        e(n + 1),
        d(n + 1),
        parent(n + 1),
        pEdge(n + 1),
        state(n + 1) {}
  void addEdge(int u, int v, Flow c, Cost w) {
    int i = e[u].size(), j = e[v].size();
    e[u].push_back(Edge(v, c, w, j));
    e[v].push_back(Edge(u, 0, -w, i));
  }
  bool findPath() {
    for (int i = 1; i <= n; ++i) {
      d[i] = oo;
      state[i] = 0;
      parent[i] = pEdge[i] = -1;
    }
    d[s] = 0;
    while (!q.empty()) q.pop_front();
    q.push_front(s);
    while (!q.empty()) {
      int u = q.front();
      q.pop_front();
      state[u] = 2;
      for (int i = 0, sz = (int)e[u].size(); i < sz; ++i)
        if (e[u][i].f < e[u][i].c) {
          int v = e[u][i].v;
          Cost tmp = d[u] + e[u][i].w;
          if (tmp + EPS < d[v]) {
            d[v] = tmp;
            parent[v] = u;
            pEdge[v] = i;
            if (state[v] == 0)
              q.push_back(v);
            else if (state[v] == 2)
              q.push_front(v);
            state[v] = 1;
          }
        }
    }
    return (parent[t] > -1);
  }
  pair<Flow, Cost> getFlow(Flow flowLimit = oo) {
    Flow flow = 0;
    Cost cost = 0;
    while (findPath()) {
      Flow add = flowLimit - flow;
      if (add <= 0) break;
      for (int v = t; v != s; v = parent[v]) {
        int u = parent[v], i = pEdge[v];
        add = min(add, e[u][i].c - e[u][i].f);
      }
      for (int v = t; v != s; v = parent[v]) {
        int u = parent[v], i = pEdge[v];
        e[u][i].f += add;
        e[v][e[u][i].inv].f -= add;
        cost += Cost(add) * e[u][i].w;
      }
      flow += add;
    }
    return make_pair(flow, cost);
  }
};
const int N = 555;
const int cInf = 1e6;
int A[N], rnk[N];
int value[N];
int main() {
  int n, m;
  unordered_set<int> S;
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", A + i);
    S.insert(A[i]);
  }
  m = min(m, (int)S.size());
  S.clear();
  int source = 2 * n + 1;
  int sink = 2 * n + 2;
  MinCostFlow<int, long long> mcmf(2 * n + 2, source, sink);
  for (int i = 1; i <= n; ++i) {
    mcmf.addEdge(source, i, 1, __builtin_popcount(A[i]));
    mcmf.addEdge(i, i + n, 1, -cInf);
    mcmf.addEdge(i + n, sink, 1, 0);
    for (int j = i + 1; j <= n; ++j) {
      int cost = 0;
      if (A[i] != A[j]) cost = __builtin_popcount(A[j]);
      mcmf.addEdge(i + n, j, 1, cost);
    }
  }
  auto res = mcmf.getFlow(m);
  long long penalty = (res.second % cInf + cInf) % cInf;
  int vID = 0, assn = n;
  for (const auto &e : mcmf.e[source]) {
    if (e.f > 0) {
      rnk[e.v] = vID++;
      ++assn;
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (const auto &e : mcmf.e[i + n]) {
      if (e.f > 0) {
        rnk[e.v] = rnk[i];
        if (A[e.v] != A[i] && e.v != sink) {
          ++assn;
        }
        break;
      }
    }
  }
  printf("%d %lld\n", assn, penalty);
  for (int i = 1; i <= n; ++i) {
    if (value[rnk[i]] != A[i]) {
      assert(A[i] != 0);
      printf("%c=%d\n", (char)(rnk[i] + 'a'), A[i]);
      value[rnk[i]] = A[i];
    }
    printf("print(%c)\n", (char)('a' + rnk[i]));
  }
  return 0;
}
