description: Even if you just leave them be, they will fall to pieces all by themselves. So, someone has to protect them, right?
  
  You find yourself playing with Teucer again in the city of Liyue. As you take the eccentric little kid around, you notice something interesting about the structure of the city.
  
  Liyue can be represented as a directed graph containing n nodes. Nodes are labeled from 1 to n. There is a directed edge from node a to node b if and only if a < b.
  
  A path between nodes a and b is defined as a sequence of edges such that you can start at a, travel along all of these edges in the corresponding direction, and end at b. The length of a path is defined by the number of edges. A rainbow path of length x is defined as a path in the graph such that there exists at least 2 distinct colors among the set of x edges.
  
  Teucer's favorite number is k. You are curious about the following scenario: If you were to label each edge with a color, what is the minimum number of colors needed to ensure that all paths of length k or longer are rainbow paths?
  
  Teucer wants to surprise his older brother with a map of Liyue. He also wants to know a valid coloring of edges that uses the minimum number of colors. Please help him with this task!
  
  Input
  
  The only line of input contains two integers n and k (2 ≤ k < n ≤ 1000). 
  
  Output
  
  On the first line, output c, the minimum colors you need to satisfy the above requirements.
  
  On the second line, print a valid edge coloring as an array of (n(n-1))/(2) integers ranging from 1 to c. Exactly c distinct colors should exist in the construction. Print the edges in increasing order by the start node first, then by the second node.
  
  For example, if n=4, the edge colors will correspond to this order of edges: (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)
  
  Examples
  
  Input
  
  
  5 3
  
  
  Output
  
  
  2
  1 2 2 2 2 2 2 1 1 1
  
  
  Input
  
  
  5 2
  
  
  Output
  
  
  3
  3 2 2 1 2 2 1 3 1 1 
  
  
  Input
  
  
  8 7
  
  
  Output
  
  
  2
  2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  
  
  Input
  
  
  3 2
  
  
  Output
  
  
  2
  1 2 2 
  
  Note
  
  The corresponding construction for the first test case looks like this: 
  
  <image> It is impossible to satisfy the constraints with less than 2 colors.
  
  The corresponding construction for the second test case looks like this: 
  
  <image> One can show there exists no construction using less than 3 colors.
solution: import java.io.OutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.stream.IntStream;
  import java.util.Arrays;
  import java.util.OptionalInt;
  import java.io.OutputStream;
  import java.io.IOException;
  import java.lang.reflect.Field;
  import java.nio.charset.StandardCharsets;
  import java.io.UncheckedIOException;
  import java.io.Closeable;
  import java.io.InputStream;
  
  /**
   * Built using CHelper plug-in
   * Actual solution is at the top
   */
  public class Main {
      public static void main(String[] args) throws Exception {
          Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
          thread.start();
          thread.join();
      }
  
      static class TaskAdapter implements Runnable {
          @Override
          public void run() {
              InputStream inputStream = System.in;
              OutputStream outputStream = System.out;
              FastInput in = new FastInput(inputStream);
              FastOutput out = new FastOutput(outputStream);
              FDefenderOfChildhoodDreams solver = new FDefenderOfChildhoodDreams();
              solver.solve(1, in, out);
              out.close();
          }
      }
  
      static class FDefenderOfChildhoodDreams {
          public void solve(int testNumber, FastInput in, FastOutput out) {
              int n = in.ri();
              int k = in.ri();
              IntRadix radix = new IntRadix(k);
              IntegerArrayList list = new IntegerArrayList(n * n);
              for (int i = 0; i < n; i++) {
                  for (int j = i + 1; j < n; j++) {
                      int x = 10;
                      while (radix.get(i, x) == radix.get(j, x)) {
                          x--;
                      }
                      list.add(x);
                  }
              }
              int[] ans = list.toArray();
              int max = Arrays.stream(ans).max().orElse(-1);
              out.println(max + 1);
              for (int x : ans) {
                  out.append(x + 1).append(' ');
              }
              out.println();
          }
  
      }
  
      static class FastInput {
          private final InputStream is;
          private byte[] buf = new byte[1 << 13];
          private int bufLen;
          private int bufOffset;
          private int next;
  
          public FastInput(InputStream is) {
              this.is = is;
          }
  
          private int read() {
              while (bufLen == bufOffset) {
                  bufOffset = 0;
                  try {
                      bufLen = is.read(buf);
                  } catch (IOException e) {
                      bufLen = -1;
                  }
                  if (bufLen == -1) {
                      return -1;
                  }
              }
              return buf[bufOffset++];
          }
  
          public void skipBlank() {
              while (next >= 0 && next <= 32) {
                  next = read();
              }
          }
  
          public int ri() {
              return readInt();
          }
  
          public int readInt() {
              boolean rev = false;
  
              skipBlank();
              if (next == '+' || next == '-') {
                  rev = next == '-';
                  next = read();
              }
  
              int val = 0;
              while (next >= '0' && next <= '9') {
                  val = val * 10 - next + '0';
                  next = read();
              }
  
              return rev ? val : -val;
          }
  
      }
  
      static class IntRadix {
          private int[] pow;
          private int base;
  
          public IntRadix(int base) {
              if (base <= 1) {
                  throw new IllegalArgumentException();
              }
              this.base = base;
              IntegerArrayList ll = new IntegerArrayList(32);
              ll.add(1);
              while (!DigitUtils.isMultiplicationOverflow(ll.tail(), base, Integer.MAX_VALUE)) {
                  ll.add(ll.tail() * base);
              }
              pow = ll.toArray();
          }
  
          public int get(int x, int i) {
              if (i >= pow.length) {
                  return 0;
              }
              return (x / pow[i] % base);
          }
  
      }
  
      static class FastOutput implements AutoCloseable, Closeable, Appendable {
          private static final int THRESHOLD = 32 << 10;
          private OutputStream writer;
          private StringBuilder cache = new StringBuilder(THRESHOLD * 2);
          private static Field stringBuilderValueField;
          private char[] charBuf = new char[THRESHOLD * 2];
          private byte[] byteBuf = new byte[THRESHOLD * 2];
  
          static {
              try {
                  stringBuilderValueField = StringBuilder.class.getSuperclass().getDeclaredField("value");
                  stringBuilderValueField.setAccessible(true);
              } catch (Exception e) {
                  stringBuilderValueField = null;
              }
              stringBuilderValueField = null;
          }
  
          public FastOutput append(CharSequence csq) {
              cache.append(csq);
              return this;
          }
  
          public FastOutput append(CharSequence csq, int start, int end) {
              cache.append(csq, start, end);
              return this;
          }
  
          private void afterWrite() {
              if (cache.length() < THRESHOLD) {
                  return;
              }
              flush();
          }
  
          public FastOutput(OutputStream writer) {
              this.writer = writer;
          }
  
          public FastOutput append(char c) {
              cache.append(c);
              afterWrite();
              return this;
          }
  
          public FastOutput append(int c) {
              cache.append(c);
              afterWrite();
              return this;
          }
  
          public FastOutput println(int c) {
              return append(c).println();
          }
  
          public FastOutput println() {
              return append('\n');
          }
  
          public FastOutput flush() {
              try {
                  if (stringBuilderValueField != null) {
                      try {
                          byte[] value = (byte[]) stringBuilderValueField.get(cache);
                          writer.write(value, 0, cache.length());
                      } catch (Exception e) {
                          stringBuilderValueField = null;
                      }
                  }
                  if (stringBuilderValueField == null) {
                      int n = cache.length();
                      if (n > byteBuf.length) {
                          //slow
                          writer.write(cache.toString().getBytes(StandardCharsets.UTF_8));
  //                writer.append(cache);
                      } else {
                          cache.getChars(0, n, charBuf, 0);
                          for (int i = 0; i < n; i++) {
                              byteBuf[i] = (byte) charBuf[i];
                          }
                          writer.write(byteBuf, 0, n);
                      }
                  }
                  writer.flush();
                  cache.setLength(0);
              } catch (IOException e) {
                  throw new UncheckedIOException(e);
              }
              return this;
          }
  
          public void close() {
              flush();
              try {
                  writer.close();
              } catch (IOException e) {
                  throw new UncheckedIOException(e);
              }
          }
  
          public String toString() {
              return cache.toString();
          }
  
      }
  
      static class SequenceUtils {
          public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
              if ((ar - al) != (br - bl)) {
                  return false;
              }
              for (int i = al, j = bl; i <= ar; i++, j++) {
                  if (a[i] != b[j]) {
                      return false;
                  }
              }
              return true;
          }
  
      }
  
      static class IntegerArrayList implements Cloneable {
          private int size;
          private int cap;
          private int[] data;
          private static final int[] EMPTY = new int[0];
  
          public IntegerArrayList(int cap) {
              this.cap = cap;
              if (cap == 0) {
                  data = EMPTY;
              } else {
                  data = new int[cap];
              }
          }
  
          public IntegerArrayList(int[] data) {
              this(0);
              addAll(data);
          }
  
          public IntegerArrayList(IntegerArrayList list) {
              this.size = list.size;
              this.cap = list.cap;
              this.data = Arrays.copyOf(list.data, size);
          }
  
          public IntegerArrayList() {
              this(0);
          }
  
          public void ensureSpace(int req) {
              if (req > cap) {
                  while (cap < req) {
                      cap = Math.max(cap + 10, 2 * cap);
                  }
                  data = Arrays.copyOf(data, cap);
              }
          }
  
          private void checkRange(int i) {
              if (i < 0 || i >= size) {
                  throw new ArrayIndexOutOfBoundsException("Access [" + i + "]");
              }
          }
  
          public void add(int x) {
              ensureSpace(size + 1);
              data[size++] = x;
          }
  
          public void addAll(int[] x) {
              addAll(x, 0, x.length);
          }
  
          public void addAll(int[] x, int offset, int len) {
              ensureSpace(size + len);
              System.arraycopy(x, offset, data, size, len);
              size += len;
          }
  
          public void addAll(IntegerArrayList list) {
              addAll(list.data, 0, list.size);
          }
  
          public int tail() {
              checkRange(0);
              return data[size - 1];
          }
  
          public int[] toArray() {
              return Arrays.copyOf(data, size);
          }
  
          public String toString() {
              return Arrays.toString(toArray());
          }
  
          public boolean equals(Object obj) {
              if (!(obj instanceof IntegerArrayList)) {
                  return false;
              }
              IntegerArrayList other = (IntegerArrayList) obj;
              return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
          }
  
          public int hashCode() {
              int h = 1;
              for (int i = 0; i < size; i++) {
                  h = h * 31 + Integer.hashCode(data[i]);
              }
              return h;
          }
  
          public IntegerArrayList clone() {
              IntegerArrayList ans = new IntegerArrayList();
              ans.addAll(this);
              return ans;
          }
  
      }
  
      static class DigitUtils {
          private DigitUtils() {
          }
  
          public static boolean isMultiplicationOverflow(long a, long b, long limit) {
              if (limit < 0) {
                  limit = -limit;
              }
              if (a < 0) {
                  a = -a;
              }
              if (b < 0) {
                  b = -b;
              }
              if (a == 0 || b == 0) {
                  return false;
              }
              //a * b > limit => a > limit / b
              return a > limit / b;
          }
  
      }
  }
  
  