#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& _p) {
  return os << "(" << _p.first << "," << _p.second << ")";
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& _V) {
  bool f = true;
  os << "[";
  for (auto v : _V) {
    os << (f ? "" : ",") << v;
    f = false;
  }
  return os << "]";
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& _S) {
  bool f = true;
  os << "(";
  for (auto s : _S) {
    os << (f ? "" : ",") << s;
    f = false;
  }
  return os << ")";
}
template <typename T, typename U>
ostream& operator<<(ostream& os, const map<T, U>& _M) {
  return os << set<pair<T, U>>(_M.begin(), _M.end());
}
const signed long long INF = 1000000100;
const long double EPS = 1e-9;
namespace MCMF {
const int MAXN = 1000005;
const int MAXM = 2000005;
int nodes, nedge, src, dest;
int point[MAXM], nex[MAXM], flow[MAXM], capa[MAXM], cost[MAXM];
int head[MAXN], dist[MAXN], expand[MAXN], pre[MAXN], edge[MAXN];
bool changed[MAXN];
void init(int n, int s, int t) {
  nodes = n;
  src = s;
  dest = t;
  nedge = 0;
  for (int(i) = (0); (i) < (nodes); (i)++) head[i] = -1;
}
void add_edge(int u, int v, int c, int w) {
  point[nedge] = v, capa[nedge] = c, cost[nedge] = w, flow[nedge] = 0,
  nex[nedge] = head[u], head[u] = (nedge++);
  point[nedge] = u, capa[nedge] = 0, cost[nedge] = -w, flow[nedge] = 0,
  nex[nedge] = head[v], head[v] = (nedge++);
}
pair<int, int> run() {
  int mflow = 0, mcost = 0;
  while (true) {
    for (int(i) = (0); (i) < (nodes); (i)++)
      dist[i] = INF, pre[i] = -1, changed[i] = 0;
    dist[src] = 0;
    changed[src] = 1;
    expand[src] = INF;
    while (true) {
      bool ok = 1;
      for (int(i) = (0); (i) < (nodes); (i)++)
        if (changed[i]) {
          changed[i] = 0;
          for (int k = head[i]; k >= 0; k = nex[k]) {
            if (flow[k] < capa[k] && dist[i] + cost[k] < dist[point[k]]) {
              dist[point[k]] = dist[i] + cost[k];
              changed[point[k]] = 1;
              pre[point[k]] = i;
              edge[point[k]] = k;
              expand[point[k]] = min(expand[i], capa[k] - flow[k]);
              ok = 0;
            }
          }
        }
      if (ok) break;
    }
    if (pre[dest] < 0) break;
    int d = expand[dest];
    mflow += d;
    mcost += d * dist[dest];
    for (int k = dest; k != src; k = pre[k]) {
      flow[edge[k]] += d;
      flow[edge[k] ^ 1] -= d;
    }
  }
  return make_pair(mflow, mcost);
}
map<pair<int, int>, int> flows() {
  map<pair<int, int>, int> ret;
  for (int(i) = (0); (i) < (nedge / 2); (i)++)
    if (flow[2 * i] != 0) {
      ret[make_pair(point[2 * i + 1], point[2 * i])] = flow[2 * i];
    }
  return ret;
}
}  // namespace MCMF
const int MAXN = 1010;
int N, M, K;
int A[MAXN];
int W[MAXN];
int Z[MAXN];
int H[MAXN];
int first;
void read_data() {
  scanf("%d %d", &N, &K);
  for (int(i) = (1); (i) <= (N); (i)++) scanf("%d", A + i);
  for (int(i) = (1); (i) <= (N); (i)++) W[i] = __builtin_popcount(A[i]);
}
int L, R, S, T;
int show(map<pair<int, int>, int>& F, bool show) {
  vector<int> U(K + 1, -1);
  int operations = 0;
  for (int(i) = (1); (i) <= (N); (i)++) {
    int id = -1;
    for (int(j) = (1); (j) <= (L); (j)++)
      if ((F.find(make_pair(1 + j, 1 + L + i)) != F.end())) {
        for (int(k) = (1); (k) <= (K); (k)++)
          if ((j <= N and U[k] == A[j]) or (j > N and U[k] == -1)) {
            if (j > N or (j <= N and A[i] != A[j])) {
              if (show) printf("%c=%d\n", char('a' + k - 1), A[i]);
              ++operations;
            }
            U[k] = A[i];
            id = k;
            break;
          }
      }
    if (show) printf("print(%c)\n", char('a' + id - 1));
    ++operations;
  }
  return operations;
}
void solve() {
  L = N + K;
  R = N;
  S = 1;
  T = 1 + L + R + 2;
  MCMF::init(T + 1, S, T);
  for (int(i) = (1); (i) <= (L); (i)++) MCMF::add_edge(1, 1 + i, 1, 0);
  for (int(i) = (1); (i) <= (N); (i)++)
    for (int(j) = (i + 1); (j) <= (N); (j)++) {
      int w = (A[i] == A[j]) ? 0 : W[j];
      MCMF::add_edge(1 + i, 1 + L + j, 1, w);
    }
  for (int(i) = (1); (i) <= (K); (i)++)
    for (int(j) = (1); (j) <= (N); (j)++)
      MCMF::add_edge(1 + N + i, 1 + L + j, 1, W[j]);
  for (int(i) = (1); (i) <= (N); (i)++) MCMF::add_edge(1 + L + i, T, 1, 0);
  int cost = MCMF::run().second;
  map<pair<int, int>, int> F = MCMF::flows();
  int operations = show(F, false);
  printf("%d %d\n", operations, cost);
  show(F, true);
}
int main() {
  read_data();
  solve();
}
