#include <bits/stdc++.h>
using namespace std;
const int INF = (int)1e9;
struct edge {
  int u, v;
  int flow;
  int cost;
  edge() {}
  edge(int u, int v, int f, int c) : u(u), v(v), flow(f), cost(c) {}
};
struct MinCostMaxFlow {
  int N;
  vector<vector<int> > G;
  vector<edge> E;
  int numEdges;
  vector<int> found, dad;
  vector<int> dist;
  MinCostMaxFlow(int N) : N(N), G(N), found(N), dist(N), dad(N), numEdges(0) {}
  void addEdge(int from, int to, int capacity, int cost) {
    G[from].push_back(numEdges++);
    E.push_back(edge(from, to, capacity, cost));
    G[to].push_back(numEdges++);
    E.push_back(edge(to, from, 0, int(-1) * cost));
  }
  bool spfa(int s, int t) {
    fill(dad.begin(), dad.end(), -1);
    fill(dist.begin(), dist.end(), INF);
    fill(found.begin(), found.end(), 0);
    queue<int> Q;
    dist[s] = 0;
    Q.push(s);
    found[s] = true;
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      if (u == t) continue;
      for (int i = 0; i < G[u].size(); ++i) {
        edge &pres = E[G[u][i]];
        int v = pres.v;
        if (pres.flow <= 0) continue;
        if (dist[u] + pres.cost < dist[v]) {
          dad[v] = G[u][i];
          dist[v] = dist[u] + pres.cost;
          if (!found[v]) Q.push(v), found[v] = true;
        }
      }
      found[u] = false;
    }
    return (dad[t] != -1);
  }
  int dfs(int s, int t) {
    int flow = INF;
    for (int i = dad[t]; i != -1; i = dad[E[i].u]) {
      if (E[i].flow < flow) flow = E[i].flow;
    }
    for (int i = dad[t]; i != -1; i = dad[E[i].u]) {
      E[i].flow -= flow;
      E[i ^ 1].flow += flow;
    }
    return flow;
  }
  pair<int, int> getMaxFlow(int s, int t) {
    int totflow = 0;
    int totcost = 0;
    while (spfa(s, t)) {
      int amt = dfs(s, t);
      totflow += amt;
      totcost += dist[t] * (int)amt;
    }
    return make_pair(totflow, totcost);
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> a(n);
  for (int i = 0; i < n; ++i) cin >> a[i];
  MinCostMaxFlow mcmf(n * 2 + m + 2);
  for (int i = 0; i < n; ++i) {
    for (int j = i + 1; j < n; ++j) {
      mcmf.addEdge(i + 1, j + n + 1 + m, 1,
                   (a[i] == a[j] ? 0 : __builtin_popcount(a[j])));
    }
  }
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < n; ++j) {
      mcmf.addEdge(i + n + 1, j + n + m + 1, 1, __builtin_popcount(a[j]));
    }
    mcmf.addEdge(0, i + n + 1, 1, 0);
  }
  for (int i = 0; i < n; ++i) {
    mcmf.addEdge(0, i + 1, 1, 0);
    mcmf.addEdge(i + n + m + 1, n + m + n + 1, 1, 0);
  }
  pair<int, int> ret = mcmf.getMaxFlow(0, n + n + m + 1);
  vector<int> who(n);
  for (int i = 1; i <= n + m; ++i) {
    for (int c : mcmf.G[i]) {
      edge e = mcmf.E[c];
      if (e.flow == 0 && e.v != 0) {
        who[e.v - n - m - 1] = i - 1;
        assert(e.u == i);
      }
    }
  }
  vector<int> last(n, -1);
  vector<string> fans;
  for (int i = 0; i < n; ++i) {
    int f = who[i];
    if (f >= n) {
      stringstream ss;
      ss << (char)(f - n + 'a') << "=" << a[i] << " ";
      ss << "print(" << (char)(f - n + 'a') << ")";
      string tmp;
      ss >> tmp;
      fans.push_back(tmp);
      ss >> tmp;
      fans.push_back(tmp);
      last[i] = f - n;
    } else {
      if (a[who[i]] == a[i]) {
        stringstream ss;
        ss << "print(" << (char)(last[who[i]] + 'a') << ")";
        string tmp;
        ss >> tmp;
        fans.push_back(tmp);
      } else {
        stringstream ss;
        ss << (char)(last[who[i]] + 'a') << "=" << a[i] << " ";
        ss << "print(" << (char)(last[who[i]] + 'a') << ")";
        string tmp;
        ss >> tmp;
        fans.push_back(tmp);
        ss >> tmp;
        fans.push_back(tmp);
      }
      last[i] = last[who[i]];
    }
  }
  cout << fans.size() << " " << ret.second << "\n";
  for (string t : fans) cout << t << "\n";
  return 0;
}
