import std.functional,
       std.algorithm,
       std.bigint,
       std.string,
       std.traits,
       std.array,
       std.range,
       std.stdio,
       std.conv;

class UnionFind {
  long[] data;

  this (size_t size) {
    data.length = size;
    foreach (ref e; data) {
      e = -1;
    }
  }

  void unite(long x, long  y) {
    x = root(x);
    y = root(y);

    if (x != y) {
      if (size(x) < size(y)) { swap(x, y); }
      data[x] += data[y];
      data[y] = x;
    }
  }

  bool same(long x, long y) {
    return root(x) == root(y);
  }

  long root(long x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }

  size_t size(long x) {
    return -data[root(x)];
  }
}

void main() {
  int[] NM = readln.chomp.split.to!(int[]);
  int N = NM[0],
      M = NM[1];
  int ans;
  int[][] es;

  foreach (_; 0..M) {
    int[] ab = readln.chomp.split.to!(int[]);
    int a = ab[0],
        b = ab[1];
    a--;
    b--;
    es ~= [a, b];
  }

  foreach (e; es) {
    UnionFind uf = new UnionFind(N);

    foreach (e2; es) {
      if (e == e2) { continue; }
      uf.unite(e2[0], e2[1]);
    }

    if (uf.size(0) != N) {
      ans++;
    }
  }

