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.*;
import java.util.*;

import static java.lang.Math.max;
import static java.lang.Math.min;

public class MainClass
{
    public static void main(String[] args)throws IOException
    {
        Reader in = new Reader();
        int n = in.nextInt();
        int k = in.nextInt();
        ArrayList<Integer>[] adj = new ArrayList[n];
        for (int i=0;i<n;i++)   adj[i] = new ArrayList<>();
        for (int i=0;i<n - 1;i++)
        {
            int x = in.nextInt() - 1;
            int y = in.nextInt() - 1;
            adj[x].add(y);
            adj[y].add(x);
        }
        MinIndexedBinaryHeap<Integer> ipq = new MinIndexedBinaryHeap<>(n);
        for (int i=0;i<n;i++) ipq.insert(i, adj[i].size());
        int levels = 0;
        Set<Integer> set = new HashSet<>();
        Set<Integer> next = new HashSet<>();
        while (!ipq.isEmpty())
        {
            List<Integer> nodes = new ArrayList<>();
            if (ipq.peekMinValue() == 0)
            {
                if (ipq.size() == 1)
                {
                    nodes.add(ipq.pollMinKeyIndex());
                    for (int v: nodes)
                    {
                        int count = 0;
                        for (int u: adj[v])
                        {
                            if (set.contains(u))    count++;
                        }
                        if (count <= 2)
                        {
                            System.out.println("No");
                            System.exit(0);
                        }
                    }
                    if (levels == k)
                    {
                        System.out.println("Yes");
                        System.exit(0);
                    }
                    else
                    {
                        System.out.println("No");
                        System.exit(0);
                    }
                }
                else
                {
                    System.out.println("No");
                    System.exit(0);
                }
            }
            while (ipq.size() > 0 && ipq.peekMinValue() == 1)
                nodes.add(ipq.pollMinKeyIndex());
            if (levels == 0)
            {
                set.addAll(nodes);
                next.clear();
                for (int v: nodes)
                {
                    for (int u: adj[v])
                    {
                        if (ipq.contains(u))
                        {
                            ipq.decrease(u, ipq.valueOf(u) - 1);
                            next.add(u);
                        }
                    }
                }
                levels++;
                continue;
            }
            levels++;
            for (int v: nodes)
            {
                int count = 0;
                for (int u: adj[v])
                {
                    if (set.contains(u))    count++;
                }
                if (count <= 2)
                {
                    System.out.println("No");
                    System.exit(0);
                }
            }
            set.clear();
            set.addAll(nodes);
            if (nodes.size() == next.size())
            {
                for (int i: nodes)
                {
                    if (!next.contains(i))
                    {
                        System.out.println("No");
                        System.exit(0);
                    }
                }
            }
            else
            {
                System.out.println("No");
                System.exit(0);
            }
            next.clear();
            for (int v: nodes)
            {
                for (int u: adj[v])
                {
                    if (ipq.contains(u))
                    {
                        ipq.decrease(u, ipq.valueOf(u) - 1);
                        next.add(u);
                    }
                }
            }
        }
        System.out.println("No");
    }
}
class MinIndexedBinaryHeap<T extends Comparable<T>> extends MinIndexedDHeap<T>
{
    public MinIndexedBinaryHeap(int maxSize)
    {
        super(2, maxSize);
    }
}
class MinIndexedDHeap<T extends Comparable<T>>
{

    // Current number of elements in the heap.
    private int sz;

    // Maximum number of elements in the heap.
    private final int N;

    // The degree of every node in the heap.
    private final int D;

    // Lookup arrays to track the child/parent indexes of each node.
    private final int[] child, parent;

    // The Position Map (pm) maps Key Indexes (ki) to where the position of that
    // key is represented in the priority queue in the domain [0, sz).
    public final int[] pm;

    // The Inverse Map (im) stores the indexes of the keys in the range
    // [0, sz) which make up the priority queue. It should be noted that
    // 'im' and 'pm' are inverses of each other, so: pm[im[i]] = im[pm[i]] = i
    public final int[] im;

    // The values associated with the keys. It is very important  to note
    // that this array is indexed by the key indexes (aka 'ki').
    public final Object[] values;

    // Initializes a D-ary heap with a maximum capacity of maxSize.
    public MinIndexedDHeap(int degree, int maxSize)
    {
        if (maxSize <= 0) throw new IllegalArgumentException("maxSize <= 0");

        D = max(2, degree);
        N = max(D + 1, maxSize);

        im = new int[N];
        pm = new int[N];
        child = new int[N];
        parent = new int[N];
        values = new Object[N];

        for (int i = 0; i < N; i++)
        {
            parent[i] = (i - 1) / D;
            child[i] = i * D + 1;
            pm[i] = im[i] = -1;
        }
    }

    public int size()
    {
        return sz;
    }

    public boolean isEmpty()
    {
        return sz == 0;
    }

    public boolean contains(int ki)
    {
        keyInBoundsOrThrow(ki);
        return pm[ki] != -1;
    }

    public int peekMinKeyIndex()
    {
        isNotEmptyOrThrow();
        return im[0];
    }

    public int pollMinKeyIndex()
    {
        int minki = peekMinKeyIndex();
        delete(minki);
        return minki;
    }

    @SuppressWarnings("unchecked")
    public T peekMinValue()
    {
        isNotEmptyOrThrow();
        return (T) values[im[0]];
    }

    public T pollMinValue()
    {
        T minValue = peekMinValue();
        delete(peekMinKeyIndex());
        return minValue;
    }

    public void insert(int ki, T value)
    {
        if (contains(ki)) throw new IllegalArgumentException("index already exists; received: " + ki);
        valueNotNullOrThrow(value);
        pm[ki] = sz;
        im[sz] = ki;
        values[ki] = value;
        swim(sz++);
    }

    @SuppressWarnings("unchecked")
    public T valueOf(int ki)
    {
        keyExistsOrThrow(ki);
        return (T) values[ki];
    }

    @SuppressWarnings("unchecked")
    public T delete(int ki)
    {
        keyExistsOrThrow(ki);
        final int i = pm[ki];
        swap(i, --sz);
        sink(i);
        swim(i);
        T value = (T) values[ki];
        values[ki] = null;
        pm[ki] = -1;
        im[sz] = -1;
        return value;
    }

    @SuppressWarnings("unchecked")
    public T update(int ki, T value)
    {
        keyExistsAndValueNotNullOrThrow(ki, value);
        final int i = pm[ki];
        T oldValue = (T) values[ki];
        values[ki] = value;
        sink(i);
        swim(i);
        return oldValue;
    }

    // Strictly decreases the value associated with 'ki' to 'value'
    public void decrease(int ki, T value)
    {
        keyExistsAndValueNotNullOrThrow(ki, value);
        if (less(value, values[ki]))
        {
            values[ki] = value;
            swim(pm[ki]);
        }
    }

    // Strictly increases the value associated with 'ki' to 'value'
    public void increase(int ki, T value)
    {
        keyExistsAndValueNotNullOrThrow(ki, value);
        if (less(values[ki], value))
        {
            values[ki] = value;
            sink(pm[ki]);
        }
    }

    /* Helper functions */

    private void sink(int i)
    {
        for (int j = minChild(i); j != -1; )
        {
            swap(i, j);
            i = j;
            j = minChild(i);
        }
    }

    private void swim(int i)
    {
        while (less(i, parent[i]))
        {
            swap(i, parent[i]);
            i = parent[i];
        }
    }

    // From the parent node at index i find the minimum child below it
    private int minChild(int i)
    {
        int index = -1, from = child[i], to = min(sz, from + D);
        for (int j = from; j < to; j++) if (less(j, i)) index = i = j;
        return index;
    }

    private void swap(int i, int j)
    {
        pm[im[j]] = i;
        pm[im[i]] = j;
        int tmp = im[i];
        im[i] = im[j];
        im[j] = tmp;
    }

    // Tests if the value of node i < node j
    @SuppressWarnings("unchecked")
    private boolean less(int i, int j)
    {
        return ((Comparable<? super T>) values[im[i]]).compareTo((T) values[im[j]]) < 0;
    }

    @SuppressWarnings("unchecked")
    private boolean less(Object obj1, Object obj2)
    {
        return ((Comparable<? super T>) obj1).compareTo((T) obj2) < 0;
    }

    @Override
    public String toString()
    {
        List<Integer> lst = new ArrayList<>(sz);
        for (int i = 0; i < sz; i++) lst.add(im[i]);
        return lst.toString();
    }

    /* Helper functions to make the code more readable. */

    private void isNotEmptyOrThrow()
    {
        if (isEmpty()) throw new NoSuchElementException("Priority queue underflow");
    }

    private void keyExistsAndValueNotNullOrThrow(int ki, Object value)
    {
        keyExistsOrThrow(ki);
        valueNotNullOrThrow(value);
    }

    private void keyExistsOrThrow(int ki)
    {
        if (!contains(ki)) throw new NoSuchElementException("Index does not exist; received: " + ki);
    }

    private void valueNotNullOrThrow(Object value)
    {
        if (value == null) throw new IllegalArgumentException("value cannot be null");
    }

    private void keyInBoundsOrThrow(int ki)
    {
        if (ki < 0 || ki >= N)
            throw new IllegalArgumentException("Key index out of bounds; received: " + ki);
    }

    // Recursively checks if this heap is a min heap. This method is used
    // for testing purposes to validate the heap invariant.
    public boolean isMinHeap()
    {
        return isMinHeap(0);
    }

    private boolean isMinHeap(int i)
    {
        int from = child[i], to = min(sz, from + D);
        for (int j = from; j < to; j++)
        {
            if (!less(i, j)) return false;
            if (!isMinHeap(j)) return false;
        }
        return true;
    }
}
class Reader
{
    final private int BUFFER_SIZE = 1 << 16;
    private final DataInputStream din;
    private final byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader()
    {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException
    {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException
    {
        byte[] buf = new byte[64]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1)
        {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException
    {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do
        {
            ret = ret * 10 + c - '0';
        }  while ((c = read()) >= '0' && c <= '9');

        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException
    {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException
    {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');

        if (c == '.')
        {
            while ((c = read()) >= '0' && c <= '9')
            {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException
    {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException
    {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException
    {
        if (din == null)
            return;
        din.close();
    }
}