#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int maxn = 603;
int n, m;
int a[maxn];
void read() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> a[i];
}
struct edge {
  int to, cost, flow, cap, rev;
};
vector<edge> adj[maxn];
void add_edge(int a, int b, int cap, int cost) {
  adj[a].push_back({b, cost, 0, cap, (int)adj[b].size()});
  adj[b].push_back({a, -cost, 0, 0, (int)adj[a].size() - 1});
}
pair<int, int> par[maxn];
int dist[maxn];
bool is_inside[maxn];
bool spfa(int s, int t) {
  for (int i = s; i <= t; i++) dist[i] = INT_MAX, is_inside[i] = false;
  deque<int> dq;
  dq.push_back(s);
  dist[s] = 0;
  is_inside[s] = true;
  while (!dq.empty()) {
    int ver = dq.front();
    dq.pop_front();
    is_inside[ver] = false;
    for (int i = 0; i < (int)adj[ver].size(); i++) {
      auto e = adj[ver][i];
      if (e.flow < e.cap && dist[ver] + e.cost < dist[e.to]) {
        par[e.to] = {ver, i};
        dist[e.to] = dist[ver] + e.cost;
        if (is_inside[e.to]) continue;
        is_inside[e.to] = true;
        if (dq.empty() || dist[e.to] < dist[dq.front()])
          dq.push_front(e.to);
        else
          dq.push_back(e.to);
      }
    }
  }
  return dist[t] != INT_MAX;
}
int mincost_maxflow(int s, int t) {
  int ans = 0;
  while (spfa(s, t)) {
    int flow = INT_MAX;
    int ver = t;
    while (ver != s) {
      int nxt = par[ver].first;
      flow = min(
          flow, adj[nxt][par[ver].second].cap - adj[nxt][par[ver].second].flow);
      ver = nxt;
    }
    ans += dist[t] * flow;
    ver = t;
    while (ver != s) {
      int nxt = par[ver].first;
      adj[nxt][par[ver].second].flow += flow;
      adj[ver][adj[nxt][par[ver].second].rev].flow -= flow;
      ver = nxt;
    }
  }
  return ans;
}
int match[maxn];
int which[maxn];
void solve() {
  int s = 0, t = 2 * n + m + 1;
  for (int i = 1; i <= n; i++) add_edge(s, i, 1, 0);
  for (int i = 1; i <= m; i++) add_edge(s, n + i, 1, 0);
  for (int i = 1; i <= n; i++) add_edge(n + m + i, t, 1, 0);
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++)
      add_edge(i, n + m + j, 1, a[i] == a[j] ? 0 : __builtin_popcount(a[j]));
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= n; j++)
      add_edge(n + i, n + m + j, 1, __builtin_popcount(a[j]));
  int ans = mincost_maxflow(s, t);
  int cnt = n;
  for (int i = 1; i <= n; i++)
    for (auto j : adj[i])
      if (j.cap == 1 && j.flow == 1) {
        if (a[i] != a[j.to - n - m]) cnt++;
        match[j.to - n - m] = i;
      }
  for (int i = 1; i <= m; i++)
    for (auto j : adj[i + n])
      if (j.cap == 1 && j.flow == 1) {
        match[j.to - n - m] = i + n;
        cnt++;
      }
  cout << cnt << " " << ans << '\n';
  for (int i = 1; i <= n; i++) {
    if (match[i] <= n) {
      int curr = which[match[i]];
      if (a[i] != a[match[i]])
        cout << (char)(curr + 'a') << "=" << a[i] << '\n';
      cout << "print(" << (char)(curr + 'a') << ")" << '\n';
      which[i] = curr;
    } else {
      int curr = match[i] - n - 1;
      cout << (char)(curr + 'a') << "=" << a[i] << '\n';
      cout << "print(" << (char)(curr + 'a') << ")" << '\n';
      which[i] = curr;
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  read();
  solve();
}
