#include <bits/stdc++.h>
using namespace std;
class MinCostMaxFlowLongLong {
 public:
  class MinCostMaxFlowEdge {
   private:
    int destination_;
    long long capacity_;
    long long cost_;
    long long flow_;

   public:
    MinCostMaxFlowEdge(int destination, long long capacity, long long cost) {
      this->destination_ = destination;
      this->capacity_ = capacity;
      this->cost_ = cost;
      this->flow_ = 0L;
    }
    MinCostMaxFlowEdge(MinCostMaxFlowEdge& ref) {
      this->destination_ = ref.destination();
      this->capacity_ = ref.capacity();
      this->cost_ = ref.cost();
      this->flow_ = ref.flow();
    }
    int destination() const { return destination_; }
    long long capacity() const { return capacity_; }
    long long cost() const { return cost_; }
    long long flow() const { return flow_; }
    void setFlow(long long flow) { flow_ = flow; }
    void addFlow(long long addend) { flow_ += addend; }
  };
  vector<vector<MinCostMaxFlowEdge*> > adj_;
  vector<long long> supply_;
  MinCostMaxFlowLongLong(int node_count) {
    supply_ = vector<long long>(node_count, 0LL);
    adj_ = vector<vector<MinCostMaxFlowEdge*> >(node_count,
                                                vector<MinCostMaxFlowEdge*>());
  }
  void addEdge(int from, int to, long long capacity, long long cost) {
    adj_[from].push_back(new MinCostMaxFlowEdge(to, capacity, cost));
  }
  void setSupply(int node, long long amount) { supply_[node] = amount; }
  long long solve(long long fail_value, bool* is_infeasible) {
    int n = ((int)supply_.size());
    vector<vector<MinCostMaxFlowEdge*> > adjcopy = adj_;
    for (int i = 0; i < ((int)adj_.size()); ++i) {
      for (int j = 0; j < ((int)adj_[i].size()); ++j) {
        adjcopy[i][j] = new MinCostMaxFlowEdge(*(adj_[i][j]));
      }
    }
    vector<long long> supplycopy = supply_;
    vector<vector<MinCostMaxFlowEdge*> > reverse_adj(
        n, vector<MinCostMaxFlowEdge*>());
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adjcopy[i].size()); ++j) {
        reverse_adj[i].push_back(NULL);
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adjcopy[i].size()); ++j) {
        if (reverse_adj[i][j] == NULL) {
          int destination = adjcopy[i][j]->destination();
          long long cost = adjcopy[i][j]->cost();
          MinCostMaxFlowEdge* new_edge = new MinCostMaxFlowEdge(i, 0, -cost);
          adjcopy[destination].push_back(new_edge);
          reverse_adj[destination].push_back(adjcopy[i][j]);
          reverse_adj[i][j] = new_edge;
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adjcopy[i].size()); ++j) {
        adjcopy[i][j]->setFlow(0);
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adjcopy[i].size()); ++j) {
        if (adjcopy[i][j]->cost() < 0 && adjcopy[i][j]->capacity() > 0) {
          supplycopy[i] -= adjcopy[i][j]->capacity();
          supplycopy[adjcopy[i][j]->destination()] += adjcopy[i][j]->capacity();
          adjcopy[i][j]->addFlow(adjcopy[i][j]->capacity());
          reverse_adj[i][j]->addFlow(-adjcopy[i][j]->destination());
        }
      }
    }
    vector<long long> pi(n, 0LL);
    vector<int> pred(n, 0), pred_adj(n, 0);
    vector<long long> shortest(n, 0LL);
    set<pair<long long, int> > pq;
    while (true) {
      vector<int> candidate_excess;
      for (int i = 0; i < n; ++i) {
        if (supplycopy[i] > 0) {
          candidate_excess.push_back(i);
        }
      }
      if (((int)candidate_excess.size()) == 0) {
        break;
      }
      for (int i = 0; i < n; ++i) {
        shortest[i] = -1LL;
        pred[i] = -1;
        pred_adj[i] = -1;
      }
      for (int i = 0; i < ((int)candidate_excess.size()); ++i) {
        shortest[candidate_excess[i]] = 0LL;
        pq.insert(make_pair(0LL, candidate_excess[i]));
      }
      while (!pq.empty()) {
        int node = pq.begin()->second;
        long long val = pq.begin()->first;
        pq.erase(pq.begin());
        if (shortest[node] != val) continue;
        for (int i = 0; i < ((int)adjcopy[node].size()); ++i) {
          if (adjcopy[node][i]->capacity() - adjcopy[node][i]->flow() == 0) {
            continue;
          }
          int dest = adjcopy[node][i]->destination();
          long long weight = adjcopy[node][i]->cost() - pi[node] + pi[dest];
          assert(weight >= 0LL);
          if (shortest[dest] == -1LL || shortest[dest] > val + weight) {
            shortest[dest] = val + weight;
            pred[dest] = node;
            pred_adj[dest] = i;
            pq.insert(make_pair(val + weight, dest));
          }
        }
      }
      vector<int> candidate_deficit;
      for (int i = 0; i < n; ++i) {
        if (supplycopy[i] < 0 && shortest[i] >= 0LL) {
          candidate_deficit.push_back(i);
        }
      }
      if (((int)candidate_deficit.size()) == 0) {
        *is_infeasible = true;
        return 0LL;
      }
      int deficit = candidate_deficit[0];
      for (int i = 1; i < ((int)candidate_deficit.size()); ++i) {
        if (shortest[candidate_deficit[i]] - pi[candidate_deficit[i]] <
            shortest[deficit] - pi[deficit]) {
          deficit = candidate_deficit[i];
        }
      }
      vector<int> nodes;
      long long flow_amt = -1LL;
      while (pred[deficit] != -1) {
        int pd = pred[deficit];
        int pa = pred_adj[deficit];
        if (flow_amt == -1LL ||
            flow_amt > adjcopy[pd][pa]->capacity() - adjcopy[pd][pa]->flow()) {
          flow_amt = adjcopy[pd][pa]->capacity() - adjcopy[pd][pa]->flow();
        }
        nodes.push_back(deficit);
        deficit = pred[deficit];
      }
      assert(flow_amt > 0LL);
      for (int i = 0; i < ((int)nodes.size()); ++i) {
        int pd = pred[nodes[i]];
        int pa = pred_adj[nodes[i]];
        adjcopy[pd][pa]->addFlow(flow_amt);
        reverse_adj[pd][pa]->addFlow(-flow_amt);
      }
      supplycopy[deficit] -= flow_amt;
      supplycopy[nodes[0]] += flow_amt;
      for (int i = 0; i < n; ++i)
        if (shortest[i] >= 0LL) {
          pi[i] -= shortest[i];
        }
    }
    for (int i = 0; i < n; ++i) {
      if (supplycopy[i] != 0LL) {
        assert(supplycopy[i] < 0LL);
        *is_infeasible = true;
        return 0LL;
      }
    }
    *is_infeasible = false;
    long long answer = 0;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adjcopy[i].size()); ++j) {
        if (adjcopy[i][j]->flow() > 0LL) {
          answer += adjcopy[i][j]->flow() * adjcopy[i][j]->cost();
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < ((int)adj_[i].size()); ++j) {
        adj_[i][j]->setFlow(adjcopy[i][j]->flow());
      }
    }
    return answer;
  }
};
int bitcnt(int num) {
  int ret = 0;
  while (num) {
    ret += num % 2;
    num /= 2;
  }
  return ret;
}
int main() {
  int n, m;
  cin >> n >> m;
  MinCostMaxFlowLongLong mcmf(n * 2 + 4);
  int tap = 2 * n;
  int ptap = 2 * n + 1;
  int sink = 2 * n + 2;
  int psink = 2 * n + 3;
  mcmf.setSupply(tap, m);
  mcmf.setSupply(sink, -m);
  mcmf.addEdge(tap, ptap, m, 0);
  mcmf.addEdge(psink, sink, m, 0);
  mcmf.addEdge(ptap, psink, m, 0);
  vector<int> vals;
  for (int(i) = 0; (i) < (n); ++(i)) {
    int a;
    cin >> a;
    vals.push_back(a);
  }
  for (int(i) = 0; (i) < (n); ++(i)) {
    mcmf.addEdge(ptap, i, 1, bitcnt(vals[i]));
    mcmf.addEdge(n + i, psink, 1, 0);
    mcmf.addEdge(i, n + i, 1, -100000);
    for (int(j) = (i + 1); (j) < (n); ++(j)) {
      if (vals[i] == vals[j]) {
        mcmf.addEdge(n + i, j, 1, 0);
      } else {
        mcmf.addEdge(n + i, j, 1, bitcnt(vals[j]));
      }
    }
  }
  bool infeasible;
  long long ans = mcmf.solve(0, &infeasible);
  vector<pair<int, int> > changes[555];
  int id = 0;
  for (int(i) = 0; (i) < (((int)mcmf.adj_[ptap].size())); ++(i)) {
    int j = mcmf.adj_[ptap][i]->destination();
    if (j >= n) continue;
    if (mcmf.adj_[ptap][i]->flow() > 0) {
      int k = j;
      while (k != psink) {
        changes[k].push_back(make_pair(id, vals[k]));
        for (int(l) = 0; (l) < (((int)mcmf.adj_[k].size())); ++(l))
          if (mcmf.adj_[k][l]->flow() > 0) {
            k = mcmf.adj_[k][l]->destination();
            break;
          }
      }
      ++id;
    }
  }
  assert(id <= m);
  vector<string> ret;
  vector<int> values(m, -1);
  char buffer[1000];
  for (int(i) = 0; (i) < (n); ++(i)) {
    for (int(j) = 0; (j) < (((int)changes[i].size())); ++(j)) {
      if (values[changes[i][j].first] == changes[i][j].second) continue;
      sprintf(buffer, "%c=%d", (char)('a' + changes[i][j].first),
              changes[i][j].second);
      values[changes[i][j].first] = changes[i][j].second;
      ret.push_back(buffer);
    }
    for (int(j) = 0; (j) < (m); ++(j))
      if (values[j] == vals[i]) {
        sprintf(buffer, "print(%c)", (char)('a' + j));
        ret.push_back(buffer);
        break;
      }
  }
  cout << ((int)ret.size()) << " " << ans + n * 100000 << endl;
  for (int(i) = 0; (i) < (((int)ret.size())); ++(i)) {
    cout << ret[i] << endl;
  }
}
