#include #include #define MAXV 10240 struct vert { size_t deg, alloc_deg; struct vert **arcs; unsigned gen; unsigned dfs; }; static struct vert verts[MAXV]; static unsigned gen; /* = 0; */ static void add_edge (struct vert *v, struct vert *dest) { if (v->deg == v->alloc_deg) { if (v->alloc_deg == 0) v->alloc_deg = 2; else v->alloc_deg *= 2; v->arcs = realloc (v->arcs, v->alloc_deg * sizeof (*v->arcs)); } v->arcs[v->deg] = dest; v->deg++; } static size_t max_deg; static unsigned dfs_index; static unsigned visit (struct vert *v, struct vert *parent) { size_t i, min; if (v->gen == gen) return v->dfs; /* printf ("Enter %d: DFS %u\n", v - verts, dfs_index); */ v->gen = gen; v->dfs = dfs_index; dfs_index++; min = v->dfs; for (i = 0; i < v->deg; i++) { if (v->arcs[i] != parent) { unsigned d; d = visit (v->arcs[i], v); if (min > d) min = d; } } if (min >= v->dfs) { /* printf ("ART %d\n", v - verts); */ if (max_deg < v->deg) max_deg = v->deg; } /* printf ("Leave %d: min %u\n", v - verts, min); */ return min; } static void walk (struct vert *v) { size_t i, c; /* printf ("TL %d: DFS %u\n", v - verts, dfs_index); */ v->gen = gen; v->dfs = dfs_index; dfs_index++; c = 0; for (i = 0; i < v->deg; i++) { if (v->arcs[i]->gen != gen) { c++; visit (v->arcs[i], v); } } if (max_deg < c) { /* printf ("TLART %d: %u\n", v - verts, c); */ max_deg = c; } } int main (void) { for (;;) { unsigned n, m, comps; struct vert *v; scanf ("%u%u", &n, &m); if (n == 0 && m == 0) break; for (v = verts; v < verts + n; v++) v->deg = 0; while (m != 0) { unsigned a, b; m--; scanf ("%u%u", &a, &b); add_edge (verts + a, verts + b); add_edge (verts + b, verts + a); } gen++; dfs_index = 0; max_deg = 0; comps = 0; for (v = verts; v < verts + n; v++) { if (v->gen != gen) { walk (v); comps++; } } /* printf ("COMPS %u, DEG %u\n", comps, max_deg); */ if (max_deg != 0) comps += max_deg - 1; printf ("%u\n", comps); } return EXIT_SUCCESS; }