#include <bits/stdc++.h>
using namespace std;
int countbit(int v) {
  int c;
  for (c = 0; v; v >>= 1) {
    c += v & 1;
  }
  return c;
}
namespace MinCostFlow {
const int inf = INT_MAX >> 2;
const int NN = 256;
struct Edge {
  int v, rev, cap, cost;
  Edge() : v(0), rev(0), cap(0), cost(0) {}
  Edge(int v, int rev, int cap, int cost)
      : v(v), rev(rev), cap(cap), cost(cost) {}
};
vector<Edge> edges[NN];
int size, dist[NN], pot[NN];
int prev[NN], prev_eid[NN];
char used[NN];
void Init(int _s) {
  size = _s;
  for (int i = 0; i < size; ++i) {
    edges[i].clear();
    dist[i] = 0;
    prev_eid[i] = 0;
    pot[i] = 0;
    prev_eid[i] = 0;
  }
}
void add_edge(int a, int b, int cap, int cost) {
  if (a == b) return;
  edges[a].push_back(Edge(b, edges[b].size() + (a == b), cap, cost));
  edges[b].push_back(Edge(a, edges[a].size() - 1, 0, -cost));
}
pair<int, int> mcmf(int s, int t, int needToFlow = inf) {
  pair<int, int> res;
  memset(pot, 0, sizeof(pot));
  while (needToFlow > 0) {
    memset(used, 0, sizeof(used));
    memset(prev, -1, sizeof(prev));
    for (int i = 0; i < size; ++i) dist[i] = inf;
    dist[s] = 0;
    char update = 1;
    while (update) {
      update = 0;
      for (int v = 0; v < size; ++v) {
        if (dist[v] == inf) continue;
        for (int i = 0; i < edges[v].size(); ++i) {
          Edge& e = edges[v][i];
          if (e.cap > 0 && dist[e.v] > dist[v] + e.cost) {
            dist[e.v] = dist[v] + e.cost;
            prev[e.v] = v;
            prev_eid[e.v] = i;
            update = 1;
          }
        }
      }
    }
    if (dist[t] == inf) break;
    for (int i = 0; i < size; ++i) dist[i] += pot[i], pot[i] = dist[i];
    int bottleNeck = inf;
    for (int v = t; v != s && v != -1; v = prev[v]) {
      bottleNeck = min(bottleNeck, edges[prev[v]][prev_eid[v]].cap);
    }
    res.first += bottleNeck;
    needToFlow -= bottleNeck;
    for (int v = t; v != s; v = prev[v]) {
      Edge& e = edges[prev[v]][prev_eid[v]];
      res.second += e.cost * bottleNeck;
      e.cap -= bottleNeck;
      edges[v][e.rev].cap += bottleNeck;
    }
  }
  return res;
}
}  // namespace MinCostFlow
int input[256];
int distinctInput[256];
int consectiveCnt[256];
int cost[256];
char buf[1024];
int main() {
  int m, n;
  int totalCost;
  while (~scanf("%d%d", &n, &m)) {
    totalCost = 0;
    int disN = 0;
    memset(distinctInput, 0, sizeof(distinctInput));
    memset(consectiveCnt, 0, sizeof(consectiveCnt));
    for (int i = 0; i < n; ++i) {
      scanf("%d", input + i);
      if (i == 0 || input[i] != input[i - 1]) {
        distinctInput[disN] = input[i];
        cost[disN] = countbit(input[i]);
        totalCost += cost[disN];
        ++disN;
      } else
        ++consectiveCnt[disN - 1];
    }
    MinCostFlow::Init(disN);
    map<int, int> prevNodeSameId;
    for (int i = 0; i < disN; ++i) {
      if (i) MinCostFlow::add_edge(i - 1, i, MinCostFlow::inf, 0);
      if (prevNodeSameId.find(distinctInput[i]) != prevNodeSameId.end()) {
        if (prevNodeSameId[distinctInput[i]] != i - 1) {
          MinCostFlow::add_edge(prevNodeSameId[distinctInput[i]] + 1, i, 1,
                                -cost[i]);
        }
      }
      prevNodeSameId[distinctInput[i]] = i;
    }
    pair<int, int> ans = MinCostFlow::mcmf(0, disN - 1, m - 1);
    ans.second = totalCost + ans.second;
    vector<string> output;
    int var[26] = {0};
    for (int i = 0; i < disN; ++i) {
      int storeVar = find(var, var + m, distinctInput[i]) - var;
      if (storeVar == m) {
        for (storeVar = 0; var[storeVar]; ++storeVar)
          ;
        var[storeVar] = distinctInput[i];
        sprintf(buf, "%c=%d", storeVar + 'a', distinctInput[i]);
        output.push_back(buf);
      }
      sprintf(buf, "print(%c)", storeVar + 'a');
      for (int j = 0; j < consectiveCnt[i] + 1; ++j) output.push_back(buf);
      if (i + 1 < disN) {
        for (int j = 0; j < MinCostFlow::edges[i + 1].size(); ++j) {
          if (MinCostFlow::edges[i + 1][j].cost == -cost[i] &&
              MinCostFlow::edges[i + 1][j].cap == 0)
            goto nextVarPrint;
        }
      }
      var[storeVar] = 0;
    nextVarPrint:;
    }
    printf("%d %d\n", output.size(), ans.second);
    for (int i = 0; i < output.size(); ++i) puts(output[i].c_str());
  }
  return 0;
}
