Someone give a strange birthday present to Ivan. It is hedgehog — connected undirected graph in which one vertex has degree at least 3 (we will call it center) and all other vertices has degree 1. Ivan thought that hedgehog is too boring and decided to make himself k-multihedgehog.

Let us define k-multihedgehog as follows:

  * 1-multihedgehog is hedgehog: it has one vertex of degree at least 3 and some vertices of degree 1.
  * For all k ≥ 2, k-multihedgehog is (k-1)-multihedgehog in which the following changes has been made for each vertex v with degree 1: let u be its only neighbor; remove vertex v, create a new hedgehog with center at vertex w and connect vertices u and w with an edge. New hedgehogs can differ from each other and the initial gift. 



Thereby k-multihedgehog is a tree. Ivan made k-multihedgehog but he is not sure that he did not make any mistakes. That is why he asked you to check if his tree is indeed k-multihedgehog.

Input

First line of input contains 2 integers n, k (1 ≤ n ≤ 10^{5}, 1 ≤ k ≤ 10^{9}) — number of vertices and hedgehog parameter.

Next n-1 lines contains two integers u v (1 ≤ u,    v ≤ n;    u ≠ v) — indices of vertices connected by edge.

It is guaranteed that given graph is a tree.

Output

Print "Yes" (without quotes), if given graph is k-multihedgehog, and "No" (without quotes) otherwise.

Examples

Input

14 2
1 4
2 4
3 4
4 13
10 5
11 5
12 5
14 5
5 13
6 7
8 6
13 6
9 6


Output

Yes


Input

3 1
1 3
2 3


Output

No

Note

2-multihedgehog from the first example looks like this:

<image>

Its center is vertex 13. Hedgehogs created on last step are: [4 (center), 1, 2, 3], [6 (center), 7, 8, 9], [5 (center), 10, 11, 12, 13].

Tree from second example is not a hedgehog because degree of center should be at least 3.
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.stream.IntStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.OptionalInt;
import java.util.NoSuchElementException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in Actual solution is at the top
 *
 * @author svilen.marchev@gmail.com
 */
public class Main {
  public static void main(String[] args) {
    InputStream inputStream = System.in;
    OutputStream outputStream = System.out;
    InputReader in = new InputReader(inputStream);
    PrintWriter out = new PrintWriter(outputStream);
    TaskE solver = new TaskE();
    solver.solve(1, in, out);
    out.close();
  }

  static class TaskE {
    int n;
    int k;
    Graph g;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
      n = in.readInt();
      k = in.readInt();
      g = new Graph(n, 2 * n);
      for (int i = 1; i < n; ++i) {
        int a = in.readInt() - 1;
        int b = in.readInt() - 1;
        g.addSimpleEdge(a, b);
        g.addSimpleEdge(b, a);
      }

      out.println(computeHedgeDegree() == k ? "Yes" : "No");
    }

    int computeHedgeDegree() {
      IntQueue queue = new IntArrayQueue(n);
      int[] addedAtLevel = new int[n];
      Arrays.fill(addedAtLevel, -1);
      for (int v = 0; v < n; ++v) {
        int degree = 0;
        for (int edge = g.firstOutbound(v); edge != -1; edge = g.nextOutbound(edge)) {
          degree++;
        }
        if (degree <= 1) {
          queue.add(v);
          addedAtLevel[v] = 0;
        }
      }

      int[] numKids = new int[n];
      boolean[] processed = new boolean[n];

      while (!queue.isEmpty()) {
        int v = queue.poll();
        processed[v] = true;

        if (addedAtLevel[v] > 0 && numKids[v] < 3) {
          return -1;
        }

        for (int edge = g.firstOutbound(v); edge != -1; edge = g.nextOutbound(edge)) {
          int u = g.destination(edge);
          if (!processed[u]) {
            numKids[u]++;
            if (addedAtLevel[u] != -1 && addedAtLevel[u] != addedAtLevel[v] + 1) {
              return -1;
            }
            if (addedAtLevel[u] == -1) {
              addedAtLevel[u] = addedAtLevel[v] + 1;
              queue.add(u);
            }
          }
        }
      }

      int max = Arrays.stream(addedAtLevel).max().getAsInt();
      long numMaxes = Arrays.stream(addedAtLevel).filter(a -> a == max).count();
      return numMaxes == 1 ? max : -1;
    }

  }

  static interface Edge {
  }

  static class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private InputReader.SpaceCharFilter filter;

    public InputReader(InputStream stream) {
      this.stream = stream;
    }

    public int read() {
      if (numChars == -1) {
        throw new InputMismatchException();
      }
      if (curChar >= numChars) {
        curChar = 0;
        try {
          numChars = stream.read(buf);
        } catch (IOException e) {
          throw new InputMismatchException();
        }
        if (numChars <= 0) {
          return -1;
        }
      }
      return buf[curChar++];
    }

    public int readInt() {
      int c = read();
      while (isSpaceChar(c)) {
        c = read();
      }
      int sgn = 1;
      if (c == '-') {
        sgn = -1;
        c = read();
      }
      int res = 0;
      do {
        if (c < '0' || c > '9') {
          throw new InputMismatchException();
        }
        res *= 10;
        res += c - '0';
        c = read();
      } while (!isSpaceChar(c));
      return res * sgn;
    }

    public boolean isSpaceChar(int c) {
      if (filter != null) {
        return filter.isSpaceChar(c);
      }
      return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
      return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
      public boolean isSpaceChar(int ch);

    }

  }

  static class Graph {
    public static final int REMOVED_BIT = 0;
    protected int vertexCount;
    protected int edgeCount;
    private int[] firstOutbound;
    private int[] firstInbound;
    private Edge[] edges;
    private int[] nextInbound;
    private int[] nextOutbound;
    private int[] from;
    private int[] to;
    private long[] weight;
    public long[] capacity;
    private int[] reverseEdge;
    private int[] flags;

    public Graph(int vertexCount) {
      this(vertexCount, vertexCount);
    }

    public Graph(int vertexCount, int edgeCapacity) {
      this.vertexCount = vertexCount;
      firstOutbound = new int[vertexCount];
      Arrays.fill(firstOutbound, -1);

      from = new int[edgeCapacity];
      to = new int[edgeCapacity];
      nextOutbound = new int[edgeCapacity];
      flags = new int[edgeCapacity];
    }

    public int addEdge(int fromID, int toID, long weight, long capacity, int reverseEdge) {
      ensureEdgeCapacity(edgeCount + 1);
      if (firstOutbound[fromID] != -1) {
        nextOutbound[edgeCount] = firstOutbound[fromID];
      } else {
        nextOutbound[edgeCount] = -1;
      }
      firstOutbound[fromID] = edgeCount;
      if (firstInbound != null) {
        if (firstInbound[toID] != -1) {
          nextInbound[edgeCount] = firstInbound[toID];
        } else {
          nextInbound[edgeCount] = -1;
        }
        firstInbound[toID] = edgeCount;
      }
      this.from[edgeCount] = fromID;
      this.to[edgeCount] = toID;
      if (capacity != 0) {
        if (this.capacity == null) {
          this.capacity = new long[from.length];
        }
        this.capacity[edgeCount] = capacity;
      }
      if (weight != 0) {
        if (this.weight == null) {
          this.weight = new long[from.length];
        }
        this.weight[edgeCount] = weight;
      }
      if (reverseEdge != -1) {
        if (this.reverseEdge == null) {
          this.reverseEdge = new int[from.length];
          Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
        }
        this.reverseEdge[edgeCount] = reverseEdge;
      }
      if (edges != null) {
        edges[edgeCount] = createEdge(edgeCount);
      }
      return edgeCount++;
    }

    protected final GraphEdge createEdge(int id) {
      return new GraphEdge(id);
    }

    public final int addFlowWeightedEdge(int from, int to, long weight, long capacity) {
      if (capacity == 0) {
        return addEdge(from, to, weight, 0, -1);
      } else {
        int lastEdgeCount = edgeCount;
        addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
        return addEdge(from, to, weight, capacity, lastEdgeCount);
      }
    }

    protected int entriesPerEdge() {
      return 1;
    }

    public final int addWeightedEdge(int from, int to, long weight) {
      return addFlowWeightedEdge(from, to, weight, 0);
    }

    public final int addSimpleEdge(int from, int to) {
      return addWeightedEdge(from, to, 0);
    }

    public final int firstOutbound(int vertex) {
      int id = firstOutbound[vertex];
      while (id != -1 && isRemoved(id)) {
        id = nextOutbound[id];
      }
      return id;
    }

    public final int nextOutbound(int id) {
      id = nextOutbound[id];
      while (id != -1 && isRemoved(id)) {
        id = nextOutbound[id];
      }
      return id;
    }

    public final int destination(int id) {
      return to[id];
    }

    public final boolean flag(int id, int bit) {
      return (flags[id] >> bit & 1) != 0;
    }

    public final boolean isRemoved(int id) {
      return flag(id, REMOVED_BIT);
    }

    protected void ensureEdgeCapacity(int size) {
      if (from.length < size) {
        int newSize = Math.max(size, 2 * from.length);
        if (edges != null) {
          edges = resize(edges, newSize);
        }
        from = resize(from, newSize);
        to = resize(to, newSize);
        nextOutbound = resize(nextOutbound, newSize);
        if (nextInbound != null) {
          nextInbound = resize(nextInbound, newSize);
        }
        if (weight != null) {
          weight = resize(weight, newSize);
        }
        if (capacity != null) {
          capacity = resize(capacity, newSize);
        }
        if (reverseEdge != null) {
          reverseEdge = resize(reverseEdge, newSize);
        }
        flags = resize(flags, newSize);
      }
    }

    protected final int[] resize(int[] array, int size) {
      int[] newArray = new int[size];
      System.arraycopy(array, 0, newArray, 0, array.length);
      return newArray;
    }

    private long[] resize(long[] array, int size) {
      long[] newArray = new long[size];
      System.arraycopy(array, 0, newArray, 0, array.length);
      return newArray;
    }

    private Edge[] resize(Edge[] array, int size) {
      Edge[] newArray = new Edge[size];
      System.arraycopy(array, 0, newArray, 0, array.length);
      return newArray;
    }

    protected class GraphEdge implements Edge {
      protected int id;

      protected GraphEdge(int id) {
        this.id = id;
      }

    }

  }

  static class IntArrayQueue implements IntQueue {
    private int[] data;
    private int from;
    private int to;

    public IntArrayQueue(int capacity) {
      data = new int[Integer.highestOneBit(capacity) << 1];
    }

    public IntArrayQueue() {
      this(3);
    }

    public IntArrayQueue(int[] array) {
      this(array.length);
      to = array.length;
      System.arraycopy(array, 0, data, 0, to);
    }

    public IntArrayQueue(net_egork_generated_collections_IntStream s) {
      addAll(s);
    }

    public IntArrayQueue(IntCollection c) {
      this(c.size());
      addAll(c);
    }

    public int size() {
      return (to - from) & (data.length - 1);
    }

    public void add(int v) {
      ensureCapacity(size() + 1);
      data[to++] = v;
      to &= data.length - 1;
    }

    public int poll() {
      if (from == to) {
        throw new NoSuchElementException();
      }
      int result = data[from++];
      from &= data.length - 1;
      return result;
    }

    public IntIterator intIterator() {
      return new IntIterator() {
        private int at = from;

        public int value() {
          if (at == to) {
            throw new NoSuchElementException();
          }
          return data[at];
        }

        public boolean advance() {
          if (!isValid()) {
            throw new NoSuchElementException();
          }
          at++;
          at &= data.length - 1;
          return isValid();
        }

        public boolean isValid() {
          return at != to;
        }

        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }

    private void ensureCapacity(int capacity) {
      if (data.length <= capacity) {
        int[] newData = new int[Integer.highestOneBit(capacity) << 1];
        if (from <= to) {
          System.arraycopy(data, from, newData, 0, size());
        } else {
          System.arraycopy(data, from, newData, 0, data.length - from);
          System.arraycopy(data, 0, newData, data.length - from, to);
        }
        to = size();
        from = 0;
        data = newData;
      }
    }

  }

  static interface IntQueue extends IntCollection {
    public int poll();

  }

  static interface IntIterator {
    public int value() throws NoSuchElementException;

    public boolean advance();

    public boolean isValid();

  }

  static interface net_egork_generated_collections_IntStream extends Iterable<Integer>,
      Comparable<net_egork_generated_collections_IntStream> {
    public IntIterator intIterator();

    default public Iterator<Integer> iterator() {
      return new Iterator<Integer>() {
        private IntIterator it = intIterator();

        public boolean hasNext() {
          return it.isValid();
        }

        public Integer next() {
          int result = it.value();
          it.advance();
          return result;
        }
      };
    }

    default public int compareTo(net_egork_generated_collections_IntStream c) {
      IntIterator it = intIterator();
      IntIterator jt = c.intIterator();
      while (it.isValid() && jt.isValid()) {
        int i = it.value();
        int j = jt.value();
        if (i < j) {
          return -1;
        } else if (i > j) {
          return 1;
        }
        it.advance();
        jt.advance();
      }
      if (it.isValid()) {
        return 1;
      }
      if (jt.isValid()) {
        return -1;
      }
      return 0;
    }

  }

  static interface IntCollection extends net_egork_generated_collections_IntStream {
    public int size();

    default public boolean isEmpty() {
      return size() == 0;
    }

    default public void add(int value) {
      throw new UnsupportedOperationException();
    }

    default public IntCollection addAll(net_egork_generated_collections_IntStream values) {
      for (IntIterator it = values.intIterator(); it.isValid(); it.advance()) {
        add(it.value());
      }
      return this;
    }

  }
}

