#include <bits/stdc++.h>
using namespace std;
bool debug;
const int inf = 1e9 + 5;
const int nax = 605;
namespace MinCost {
struct Edge {
  int w, c, v, rev;
  Edge(int _w, int _c, int _v, int _rev) : w(_w), c(_c), v(_v), rev(_rev) {}
};
int odl[nax], pot[nax], pop[nax], pop_kraw[nax];
vector<Edge> v[nax];
bool bylo[nax];
void init(int n) {
  for (int i = 0; i <= n; ++i) v[i].clear();
}
void AddEdge(int a, int b, int cap, int cost) {
  v[a].push_back(Edge(b, cap, cost, int(v[b].size()) + (a == b)));
  v[b].push_back(Edge(a, 0, -cost, int(v[a].size() - 1)));
}
pair<int, int> MinCostMaxFlow(int s, int t, int n) {
  int flow = 0, cost = 0;
  for (int i = 0; i <= n; ++i) pot[i] = 0;
  while (true) {
    for (int i = 0; i <= n; ++i) {
      odl[i] = inf;
      bylo[i] = false;
    }
    odl[s] = 0;
    for (int k = 0; k <= (n)-1; ++k) {
      int x = 0;
      int najm = inf;
      for (int i = 0; i <= n; ++i)
        if (!bylo[i] && najm > odl[i]) {
          x = i;
          najm = odl[i];
        }
      bylo[x] = true;
      int dl = v[x].size();
      for (int i = 0; i <= (dl)-1; ++i)
        if (v[x][i].c > 0 &&
            odl[v[x][i].w] > odl[x] + pot[x] - pot[v[x][i].w] + v[x][i].v) {
          odl[v[x][i].w] = odl[x] + pot[x] - pot[v[x][i].w] + v[x][i].v;
          pop[v[x][i].w] = x;
          pop_kraw[v[x][i].w] = i;
        }
    }
    if (odl[t] == inf) break;
    for (int i = 0; i <= n; ++i) pot[i] += odl[i];
    int x = t;
    int cap = inf;
    while (x != s) {
      cap = min(cap, v[pop[x]][pop_kraw[x]].c);
      x = pop[x];
    }
    flow += cap;
    x = t;
    while (x != s) {
      cost += v[pop[x]][pop_kraw[x]].v * cap;
      v[pop[x]][pop_kraw[x]].c -= cap;
      v[x][v[pop[x]][pop_kraw[x]].rev].c += cap;
      x = pop[x];
    }
  }
  return make_pair(flow, cost);
}
};  // namespace MinCost
using namespace MinCost;
int n, m;
int t[nax], numer[nax];
int main(int argc, char* argv[]) {
  debug = argc > 1;
  scanf("%d%d", &n, &m);
  init(2 * n + m + 1);
  for (int i = 0; i <= (m)-1; ++i) AddEdge(2 * n + i + 1, 2 * n + m + 1, 1, 0);
  for (int i = 1; i <= n; ++i) scanf("%d", &t[i]);
  for (int i = 1; i <= n; ++i) {
    int pc = __builtin_popcount(t[i]);
    AddEdge(0, i, 1, 0);
    AddEdge(i + n, 2 * n + m + 1, 1, 0);
    for (int j = 0; j <= (m)-1; ++j) AddEdge(i, 2 * n + j + 1, 1, pc);
    for (int j = 1; j <= i - 1; ++j)
      AddEdge(i, j + n, 1, t[i] == t[j] ? 0 : pc);
  }
  int ile = 0;
  int koszt = MinCostMaxFlow(0, 2 * n + m + 1, 2 * n + m + 1).second;
  int ile_zajetych = 0;
  for (int i = 1; i <= n; ++i) {
    int id = -1;
    for (auto j : v[i])
      if (j.c == 0) {
        id = j.w;
        break;
      }
    if (id > 2 * n) {
      numer[i] = ile_zajetych;
      ++ile;
      ++ile_zajetych;
    } else {
      numer[i] = numer[id - n];
      if (t[i] != t[id - n]) ++ile;
    }
    ++ile;
  }
  printf("%d %d\n", ile, koszt);
  ile_zajetych = 0;
  for (int i = 1; i <= n; ++i) {
    int id = -1;
    for (auto j : v[i])
      if (j.c == 0) {
        id = j.w;
        break;
      }
    if (id > 2 * n) {
      numer[i] = ile_zajetych;
      printf("%c=%d\n", 'a' + ile_zajetych, t[i]);
      ++ile_zajetych;
    } else {
      numer[i] = numer[id - n];
      if (t[i] != t[id - n]) printf("%c=%d\n", 'a' + numer[i], t[i]);
    }
    printf("print(%c)\n", 'a' + numer[i]);
  }
  return 0;
}
