#include <bits/stdc++.h>
using namespace std;
int n, st, ed, dist[2000005], inq[2000005], prevv[2000005], preve[2000005],
    cnt[2000005], que[2000005], x[2000005], vis[2000005];
struct edge {
  int to, cap, cost, rev, idx;
};
struct node {
  char v1;
  int v2, v3;
} op[2000005];
vector<edge> G[2000005];
inline void add(int from, int to, int cap, int cost, int idx) {
  G[from].push_back((edge){to, cap, cost, (int)G[to].size(), idx});
  G[to].push_back((edge){from, 0, -cost, (int)G[from].size() - 1, 100000000});
}
inline bool SPFA() {
  bool find = false;
  int head = 0, rear = 0;
  for (int i = 0; i < n; i++) cnt[i] = inq[i] = 0, dist[i] = 100000000;
  inq[st] = 1;
  dist[st] = 0;
  cnt[st]++;
  que[rear++] = st;
  while (head != rear) {
    int u = que[head++], siz = (int)G[u].size();
    inq[u] = 0;
    for (int i = 0; i < siz; i++) {
      edge &e = G[u][i];
      if (e.cap && dist[e.to] > dist[u] + e.cost) {
        find = true;
        dist[e.to] = dist[u] + e.cost;
        prevv[e.to] = u;
        preve[e.to] = i;
        if (!inq[e.to]) {
          inq[e.to] = 1;
          cnt[e.to]++;
          if (cnt[e.to] == n) return false;
          que[rear++] = e.to;
        }
      }
    }
  }
  return find;
}
inline int MCMF() {
  int minw = 0;
  while (SPFA()) {
    int d = 100000000;
    for (int u = ed; u != st; u = prevv[u])
      d = min(d, G[prevv[u]][preve[u]].cap);
    for (int u = ed; u != st; u = prevv[u]) {
      edge &e = G[prevv[u]][preve[u]];
      e.cap -= d;
      G[u][e.rev].cap += d;
    }
    minw += d * dist[ed];
  }
  return minw;
}
inline int cal(int x) {
  int ret = 0;
  while (x) {
    if (x % 2 == 1) ret++;
    x /= 2;
  }
  return ret;
}
int main() {
  int m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%d", &x[i]);
  st = 3 * n, ed = 3 * n + 1;
  add(st, 0, m, 0, 100000000);
  add(3 * n - 3, ed, m, 0, 100000000);
  add(3 * n - 1, ed, m, 0, 100000000);
  for (int i = 0; i < n; i++) {
    add(i * 3, i * 3 + 1, 1, cal(x[i]), 100000000);
    add(i * 3 + 1, i * 3 + 2, 1, -1000000, 100000000);
    if (i != n - 1)
      add(i * 3, (i + 1) * 3, m, 0, 100000000),
          add(i * 3 + 2, (i + 1) * 3, 1, 0, 1);
    for (int j = i + 1; j < n; j++)
      if (x[i] == x[j]) {
        add(i * 3 + 2, j * 3 + 1, 1, 0, 1);
        break;
      }
  }
  n = n * 3 + 2;
  int ans1 = MCMF() + (n - 2) / 3 * 1000000, ans2 = 0;
  n = (n - 2) / 3;
  for (int i = 0; i < n; i++) op[i].v3 = 0;
  for (int i = 0; i < m; i++) vis[i] = 0;
  for (int i = 0; i < n; i++) {
    int j;
    for (j = 0; j < m; j++)
      if (vis[j] == i) {
        vis[j] = 0;
        break;
      }
    if (!op[i].v3) {
      for (j = 0; j < m; j++)
        if (vis[j] == 0) break;
      op[i].v3 = 1;
      op[i].v1 = j + 'a';
      op[i].v2 = x[i];
      ans2 += 2;
    }
    int u = 3 * i + 2, siz = (int)G[u].size(), k;
    for (k = 0; k < siz; k++)
      if (G[u][k].idx != 100000000 && !G[u][k].cap) break;
    if (k == siz) continue;
    int v = G[u][k].to;
    if (v == ed)
      break;
    else if (v % 3 == 1)
      op[(v - 1) / 3].v3 = 2, op[(v - 1) / 3].v1 = j + 'a',
                   op[(v - 1) / 3].v2 = x[i], vis[j] = (v - 1) / 3, ans2++;
  }
  printf("%d %d\n", ans2, ans1);
  for (int i = 0; i < n; i++) {
    if (op[i].v3 == 1) {
      printf("%c=%d\n", op[i].v1, op[i].v2);
      printf("print(%c)\n", op[i].v1);
    } else
      printf("print(%c)\n", op[i].v1);
  }
  return 0;
}
