#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000;
const int MAXM = 100000;
const int INF = 1000000;
int n, m;
int a[250], variable[250], match[250];
vector<string> ans;
int s, t, nodes, edges;
int head[MAXN], adj[MAXM], from[MAXM], to[MAXM], cap[MAXM], cost[MAXM];
int dist[MAXN], pre[MAXN], q[MAXN], visited[MAXN];
void addEdge(int From, int To, int Cap, int Cost) {
  adj[edges] = head[From];
  from[edges] = From;
  to[edges] = To;
  cap[edges] = Cap;
  cost[edges] = Cost;
  head[From] = edges++;
  adj[edges] = head[To];
  from[edges] = To;
  to[edges] = From;
  cap[edges] = 0;
  cost[edges] = -Cost;
  head[To] = edges++;
}
int minCostFlow() {
  int ret = 0;
  while (1) {
    for (int i = 0; i < nodes; i++) dist[i] = INF;
    dist[s] = 0;
    memset(visited, 0, sizeof(visited));
    visited[s] = 1;
    int l = 0, r = 0;
    q[r++] = s;
    while (l != r) {
      int cur = q[l++];
      if (l == nodes) l = 0;
      visited[cur] = 0;
      for (int i = head[cur]; i != -1; i = adj[i])
        if (cap[i] > 0 && dist[to[i]] > dist[cur] + cost[i]) {
          dist[to[i]] = dist[cur] + cost[i];
          pre[to[i]] = i;
          if (!visited[to[i]]) {
            visited[to[i]] = 1;
            q[r++] = to[i];
            if (r == nodes) r = 0;
          }
        }
    }
    if (dist[t] == INF) break;
    ret += dist[t];
    int cur = t;
    while (cur != s) {
      if (cur % 2 == 1 && cur < 2 * n) match[cur / 2] = from[pre[cur]];
      cap[pre[cur]]--;
      cap[pre[cur] ^ 1]++;
      cur = from[pre[cur]];
    }
  }
  return ret;
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> a[i];
  nodes = n * 2 + m + 2;
  edges = 0;
  s = nodes - 1;
  t = nodes - 2;
  memset(head, -1, sizeof(head));
  for (int i = 0; i < n; i++) {
    addEdge(s, i * 2, 1, 0);
    addEdge(i * 2 + 1, t, 1, 0);
    for (int j = i + 1; j < n; j++)
      addEdge(i * 2, j * 2 + 1, 1,
              (a[i] == a[j]) ? 0 : __builtin_popcount(a[j]));
  }
  for (int i = 0; i < m; i++) {
    addEdge(s, n * 2 + i, 1, 0);
    for (int j = 0; j < n; j++)
      addEdge(n * 2 + i, j * 2 + 1, 1, __builtin_popcount(a[j]));
  }
  int penalty = minCostFlow();
  for (int i = 0; i < n; i++) {
    char ch;
    ostringstream s;
    if (match[i] >= 2 * n) {
      variable[i] = match[i] - 2 * n;
      ch = 'a' + variable[i];
      s.str("");
      s << ch << "=" << a[i];
      ans.push_back(s.str());
      s.str("");
      s << "print(" << ch << ")";
      ans.push_back(s.str());
    } else {
      variable[i] = variable[match[i] / 2];
      ch = 'a' + variable[i];
      if (a[i] != a[match[i] / 2]) {
        s.str("");
        s << ch << "=" << a[i];
        ans.push_back(s.str());
      }
      s.str("");
      s << "print(" << ch << ")";
      ans.push_back(s.str());
    }
  }
  cout << ans.size() << " " << penalty << endl;
  for (int i = 0; i < ans.size(); i++) cout << ans[i] << endl;
  return 0;
}
