Problem:
Problem H:
Twenty Questions
Consider a closed world and a set of features that are defined for all the objects in the world.
Each feature can be answered with "yes" or "no". Using those features, we can identify any
object from the rest of the objects in the world. In other words, each object can be represented
as a fixed-length sequence of booleans. Any object is different from other objects by at least
one feature.
You would like to identify an object from others. For this purpose, you can ask a series of
questions to someone who knows what the object is. Every question you can ask is about one
of the features. He/she immediately answers each question with "yes" or "no" correctly. You
can choose the next question after you get the answer to the previous question.
You kindly pay the answerer 100 yen as a tip for each question. Because you don' t have surplus
money, it is necessary to minimize the number of questions in the worst case. You don’t know
what is the correct answer, but fortunately know all the objects in the world. Therefore, you
can plan an optimal strategy before you start questioning.
The problem you have to solve is: given a set of boolean-encoded objects, minimize the maximum
number of questions by which every object in the set is identifiable.
Input
The input is a sequence of multiple datasets. Each dataset begins with a line which consists of
two integers,
m
and
n
: the number of features, and the number of objects, respectively. You
can assume 0 <
m
≤ 11 and 0 <
n
≤ 128. It is followed by
n
lines, each of which corresponds
to an object. Each line includes a binary string of length
m
which represent the value ("yes" or
"no") of features. There are no two identical objects.
The end of the input is indicated by a line containing two zeros. There are at most 100 datasets.
Output
For each dataset, minimize the maximum number of questions by which every object is identifiable and output the result.
Sample Input
8 1
11010101
11 4
00111001100
01001101011
01010000011
01100110001
11 16
01000101111
01011000000
01011111001
01101101001
01110010111
01110100111
10000001010
10010001000
10010110100
10100010100
10101010110
10110100010
11001010011
11011001001
11111000111
11111011101
11 12
10000000000
01000000000
00100000000
00010000000
00001000000
00000100000
00000010000
00000001000
00000000100
00000000010
00000000001
00000000000
9 32
001000000
000100000
000010000
000001000
000000100
000000010
000000001
000000000
011000000
010100000
010010000
010001000
010000100
010000010
010000001
010000000
101000000
100100000
100010000
100001000
100000100
100000010
100000001
100000000
111000000
110100000
110010000
110001000
110000100
110000010
110000001
110000000
0 0
Output for the Sample Input
0
2
4
11
9

Submitted solutions:

code_snippet: #include<iostream>
#include<fstream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<list>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<vector>
#include<functional>
#include<string>
#define INF 1000000007
#define ll long long
#define rep(i,k) for(int i=g.start[k];i!=INF;i=g.next[i])

using namespace std;
int n,m,p[130];
int cnt[1<<11][1<<11],dp[1<<11][1<<11];

void Init()
{
	string t;
	memset(cnt,0,sizeof(cnt));
	memset(dp,-1,sizeof(dp));
	for(int i=0;i<n;i++){
		cin>>t;
		for(int j=0;j<t.length();j++)
			p[i]=(p[i]<<1)+t[j]-'0';
	}
	for(int i=0;i<(1<<m);i++)
		for(int j=0;j<n;j++)
			cnt[i][i&p[j]]++;
}
int DP(int mask1,int mask2)
{
	if(dp[mask1][mask2]!=-1)return dp[mask1][mask2];
	if(cnt[mask1][mask2]<=1)return dp[mask1][mask2]=0;
	dp[mask1][mask2]=INF;
	for(int i=0;i<m;i++)
	{
		if(mask1&(1<<i))continue;
		int& ans=dp[mask1][mask2];
		int tmp=mask1^(1<<i);
		ans=min(ans,max(DP(tmp,mask2),DP(tmp,mask2^(1<<i)))+1);
	}
	return dp[mask1][mask2];
}
int main()
{
	ios::sync_with_stdio(false);
	
	while(cin>>m>>n&&(n||m))
	{
		Init();
		cout<<DP(0,0)<<endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 36156
final_rank: 17

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int m, n;
    cin >> m >> n;
    while(m) {
        vector<string> t(n);
        rep(i, n) cin >> t[i];
        vector<string> s(m, string(n, '0'));
        rep(i, n) rep(j, m) s[j][i] = t[i][j];
        map<pair<vector<int>, int>, int> mp;
        auto dfs = [&](auto &&dfs, vector<int> v, int bit) -> int {
            if((int)v.size() <= 1) return 0;
            if(mp.count({v, bit})) return mp[{v, bit}];
            int ans = m;
            
            for(int i = 0; i < m; i ++) {
                if(bit >> i & 1) continue;
                vector<int> nx1, nx2;
                foa(j, v) {
                    if(s[i][j] == '1') nx1.pb(j);
                    else nx2.pb(j);
                }
                if(nx1.empty() or nx2.empty()) continue;
                ans = min(ans, max(dfs(dfs, nx1, bit | (1 << i)), dfs(dfs, nx2, bit | (1 << i))) + 1);
            }
            
            return mp[{v, bit}] = ans;
        };

        vector<int> base(n);
        iota(all(base), 0);
        cout << dfs(dfs, base, 0) << endl;
        cin >> m >> n;
    }
    return 0;
}
accuracy: 1
time_ms: 600
memory_kb: 9224
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0) return 0;
    vector<vector<int>> A(M,vector<int>(N));
    rep(i,0,M) {
        rep(j,0,N) {
            char C;
            cin >> C;
            A[i][j] = C - '0';
        }
    }
    vector<int> DP((int)pow(3,N),inf);
    rep(i,0,(int)pow(3,N)) {
        vector<int> V(N);
        int I = i;
        rep(j,0,N) {
            V[j] = I % 3;
            I /= 3;
        }
        vector<bool> B(M,true);
        rep(j,0,N) {
            if (V[j] == 2) continue;
            rep(k,0,M) {
                if (A[k][j] != V[j]) B[k] = false;
            }
        }
        int COUNT = 0;
        rep(j,0,M) if (B[j]) COUNT++;
        if (COUNT <= 1) {
            DP[i] = 0;
            continue;
        }
        rep(j,0,N) {
            if (V[j] == 2) {
                int MAX = 0;
                rep(k,0,2) {
                    V[j] = k;
                    int X = 0;
                    rrep(l,0,N) {
                        X *= 3;
                        X += V[l];
                    }
                    chmax(MAX,DP[X]);
                    V[j] = 2;
                }
                chmin(DP[i],MAX+1);
            }
        }
    }
    cout << DP[pow(3,N)-1] << endl;
}
}
accuracy: 1
time_ms: 1450
memory_kb: 4452
final_rank: 19

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int m, int n) {
    vector<string> s = in(n);

    map<vector<int>, int> memo;
    vector<int> used(m, 0);
    auto dfs = [&](auto self, vector<int> a) -> int {
        if(a.size() <= 1) return 0;
        if(memo.count(a)) return memo[a];

        int ans = 1e9;
        for(int i : rep(m)) if(not used[i]) {
            vector<int> a0, a1;
            for(int id : a) {
                (s[id][i] == '0' ? a0 : a1).push_back(id);
            }
            if(a0.size() == 0 or a1.size() == 0) continue;
            used[i] = 1;
            chmin(ans, 1 + max(self(self, a0), self(self, a1)));
            used[i] = 0;
        }
        return memo[a] = ans;
    };

    return dfs(dfs, iota(n));
}

int main() {
    while(true) {
        int m = in(), n = in();
        if(make_pair(m, n) == make_pair(0, 0)) return 0;
        print(solve(m, n));
    }
}
accuracy: 1
time_ms: 150
memory_kb: 5500
final_rank: 3

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

map<pair<vector<int>, int>, int> mp;
string qes[128];

int search(vector<int> &vi, int depth, int used, int m, int n) {
  pair<vector<int>, int> p = make_pair(vi, used);
  if (mp.count(p))
    return mp[p];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  vector<int> a, b;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    a.clear(); b.clear();
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }
  return mp[p] = res;
}

int main() {
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 780
memory_kb: 8648
final_rank: 10

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

map<pair<vector<int>, int>, int> mp;
string qes[128];

int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];

  if (vi.size() > (1 << (m - depth)))
    return 100;

  if (vi.size() == 1)
    return depth;

  int res = 100;

  vector<int> a(n), b(n); // Initialize a and b with the maximum possible size

  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;

    a.clear();
    b.clear();

    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }

    if (a.empty() || b.empty())
      continue;

    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }

  mp[make_pair(vi, used)] = res; // Store the result in mp

  return res;
}

int main() {
  int m, n;

  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];

    vector<int> vi(n);

    for (int i = 0; i < n; i++)
      vi[i] = i;

    mp.clear();

    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 830
memory_kb: 9064
final_rank: 11

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;

map<pair<vector<int>, int>, int> mp;
string qes[128];

int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];

  if (vi.size() > (1 << (m - depth)))
    return 100;

  if (vi.size() == 1)
    return depth;

  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;

    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }

    if (a.empty() || b.empty())
      continue;

    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }

  return mp[make_pair(vi, used)] = res;
}

int main() {
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];

    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;

    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 920
memory_kb: 8696
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef vector<int> Vi;
const int INF = 1<<29;
int m, n, obj[130];
map<Vi, int> mp;
int dfs(Vi vi){
    if(vi.size()<2) return 0;
    if(mp.count(vi)>0) return mp[vi];
    int res = INF;
    for(int i=0;i<m;i++){
        Vi v0, v1;
        for(int j=0;j<vi.size();j++){
            int num = vi[j];
            if(obj[num]&1<<i) v1.push_back(num);
            else v0.push_back(num);
        }
        if(v0.size()<1 || v1.size()<1) continue;
        res = min(res, max(dfs(v0), dfs(v1))+1);
    }
    return mp[vi] = res;
}
int main(){
    string s;
    while(cin >> m >> n, m){
        Vi vi;
        for(int i=0;i<n;i++){
            cin >> s;
            int ob = 0;
            for(int j=0;j<m;j++){
                if(s[j]=='1') ob |= 1<<j;
            }
            obj[i] = ob;
            vi.push_back(i);
        }
        cout << dfs(vi) << endl;
        mp.clear();
    }
    return(0);
}
accuracy: 1
time_ms: 260
memory_kb: 5392
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
	while (true) {
		int M, N;
		cin >> M >> N;
		if (M == 0 && N == 0) {
			break;
		}
		vector<string> S(N);
		for (int i = 0; i < N; i++) {
			cin >> S[i];
		}
		vector<int> power(M + 1);
		power[0] = 1;
		for (int i = 1; i <= M; i++) {
			power[i] = power[i - 1] * 3;
		}
		vector<int> cnt(power[M]);
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < (1 << M); j++) {
				int code = 0;
				for (int k = 0; k < M; k++) {
					code += ((j >> k) & 1 ? 2 : int(S[i][k] - '0')) * power[k];
				}
				cnt[code] += 1;
			}
		}
		const int INF = 1012345678;
		vector<int> dp(power[M]);
		for (int i = 0; i < power[M]; i++) {
			if (cnt[i] <= 1) {
				dp[i] = 0;
			}
			else {
				dp[i] = INF;
				for (int j = 0; j < M; j++) {
					int z = i / power[j] % 3;
					if (z == 2) {
						int resl = dp[i - 2 * power[j]];
						int resr = dp[i - 1 * power[j]];
						dp[i] = min(dp[i], max(resl, resr) + 1);
					}
				}
			}
		}
		cout << dp[power[M] - 1] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 4324
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

bool is_end = false;

const int INF = 1e9;
int dp[1<<11][1<<11];

void init()
{
	for (int i = 0; i < (1<<11); ++i)
	{
		for (int j = 0; j < (1<<11); ++j)
		{
			dp[i][j] = INF;
		}
	}
	return;
}

void calc()
{
	int M, N; cin >> M >> N;
	
	if (M == 0)
	{
		is_end = true;
		return;
	}
	
	vector<int> quest(N);
	for (int i = 0; i < N; ++i)
	{
		string S; cin >> S;
		bitset<11> bs(S);
		quest[i] = bs.to_ullong();
	}
	
	init();
	
	for (int bit = (1<<M)-1; bit >= 0; --bit)
	{
		for (int sbit = bit; sbit >= 0; sbit = bit & (sbit-1))
		{
			int sum = 0;
			for (int i = 0; i < N; ++i)
			{
				if ((quest[i] & bit) == sbit) {sum += 1;}
			}
			
			if (sum <= 1)
			{
				dp[bit][sbit] = 0;
			}
			else
			{
				for (int i = 0; i < M; ++i)
				{
					if ((bit & (1<<i))) {continue;}
					int nbit = 1<<i;
					chmin(dp[bit][sbit], 1 + max(dp[bit^nbit][sbit], dp[bit^nbit][sbit^nbit]));
				}
			}
			
			if (sbit == 0) {break;}
		}
	}
	
	int res = dp[0][0];
	cout << res << endl;
	
	return;
}

int main()
{
	while (!is_end)
	{
		calc();
	}
	
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 19580
final_rank: 6

code_snippet: #include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<pair<vector<int>, int>, int> mp;
string qes[128];
int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }
  return mp[make_pair(vi, used)] = res;
}
int main() {
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 920
memory_kb: 8572
final_rank: 13

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<pair<vector<int>, int>, int> mp;
string qes[128];
int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }
  return mp[make_pair(vi, used)] = res;
}
int main() {
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 920
memory_kb: 8668
final_rank: 14

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<pair<vector<int>, int>, int> mp;
vector<string> qes(128);
int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count({vi, used}))
    return mp[{vi, used}];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }
  return mp[{vi, used}] = res;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 870
memory_kb: 8664
final_rank: 12

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

map<pair<vector<int>, int>, int> mp;
string qes[128];

int search(const vector<int>& vi, int depth, int used, int m) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    int a_used = used | (1 << i);
    int res_a, res_b;
    if (mp.count(make_pair(a, a_used))) {
      res_a = mp[make_pair(a, a_used)];
    } else {
      res_a = search(a, depth + 1, a_used, m);
      mp[make_pair(a, a_used)] = res_a;
    }
    int b_used = a_used;
    if (mp.count(make_pair(b, b_used))) {
      res_b = mp[make_pair(b, b_used)];
    } else {
      res_b = search(b, depth + 1, b_used, m);
      mp[make_pair(b, b_used)] = res_b;
    }
    res = min(res, max(res_a, res_b));
  }
  return mp[make_pair(vi, used)] = res;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m) << '\n';
  }
}
accuracy: 1
time_ms: 960
memory_kb: 14144
final_rank: 16

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<pair<int, int>, int> mp;
string qes[128];
int search(vector<int> &vi, int depth, int used, int m, int n) {
  auto key = make_pair(vi.size(), used);
  if (mp.count(key))
    return mp[key];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    res = min(res, max(search(a, depth + 1, used | (1 << i), m, n),
                       search(b, depth + 1, used | (1 << i), m, n)));
  }
  return mp[key] = res;
}
int main() {
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << endl;
  }
}
accuracy: 1
time_ms: 110
memory_kb: 4044
final_rank: 2

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<pair<vector<int>, int>, int> mp;
string qes[128];
int search(vector<int> &vi, int depth, int used, int m, int n) {
  if (mp.count(make_pair(vi, used)))
    return mp[make_pair(vi, used)];
  if (vi.size() > (1 << (m - depth)))
    return 100;
  if (vi.size() == 1)
    return depth;
  int res = 100;
  for (int i = 0; i < m; i++) {
    if ((used >> i) & 1)
      continue;
    vector<int> a, b;
    for (int j = 0; j < vi.size(); j++) {
      if (qes[vi[j]][i] == '0')
        a.push_back(vi[j]);
      else
        b.push_back(vi[j]);
    }
    if (a.empty() || b.empty())
      continue;
    int a_res = search(a, depth + 1, used | (1 << i), m, n);
    int b_res = search(b, depth + 1, used | (1 << i), m, n);
    res = min(res, max(a_res, b_res));
  }
  return mp[make_pair(vi, used)] = res;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  int m, n;
  while (cin >> m >> n, m) {
    for (int i = 0; i < n; i++)
      cin >> qes[i];
    vector<int> vi(n);
    for (int i = 0; i < n; i++)
      vi[i] = i;
    mp.clear();
    cout << search(vi, 0, 0, m, n) << '\n';
  }
}
accuracy: 1
time_ms: 630
memory_kb: 9300
final_rank: 8

code_snippet: #include <stdio.h>

#include <algorithm>
#include <vector>
using namespace std;
char str[150][13];
int dp[180000];
int pow3[13];
int m, n;
int calc(int a) {
  if (~dp[a]) return dp[a];
  vector<int> c;
  int key[13];
  for (int i = 0; i < m; i++) key[i] = a % pow3[i + 1] / pow3[i];
  for (int i = 0; i < n; i++) {
    bool ok = true;
    for (int j = 0; j < m; j++) {
      if (key[j] && str[i][j] - '0' + 1 != key[j]) ok = false;
    }
    if (ok) c.push_back(i);
  }
  if (c.size() <= 1) return dp[a] = 0;
  int ret = 99999999;
  for (int i = 0; i < m; i++) {
    if (key[i]) continue;
    int L = calc(a + pow3[i]);
    int R = calc(a + pow3[i] * 2);
    ret = min(ret, max(L, R) + 1);
  }
  return dp[a] = ret;
}
int main() {
  int a, b;
  pow3[0] = 1;
  for (int i = 1; i < 13; i++) pow3[i] = pow3[i - 1] * 3;
  while (scanf("%d%d", &a, &b), a) {
    n = b;
    m = a;
    for (int i = 0; i < b; i++) scanf("%s", str[i]);
    for (int i = 0; i < pow3[a]; i++) dp[i] = -1;
    printf("%d\n", calc(0));
  }
}
accuracy: 1
time_ms: 930
memory_kb: 3468
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
using namespace std;

struct Solver{
    int n, m;
    vector<int> a;
    map<pair<int, vector<int>>, int> mem;
    Solver(int n, int m): n(n), m(m), a(vector<int>(n)){
        for(int i = 0; i < n; i++){
            string line; cin >> line;
            for(int j = 0; j < m; j++){
                if(line[j] == '1') a[i] |= 1 << j;
            }
        }
    }

    int f(int used, vector<int> a){
        if(mem.count({used, a}) == 1) return mem[{used, a}];
        if(a.size() <= 1) return 0;
        if(a.size() == 2) return 1;
        int res = 1 << 30;
        for(int i = 0; i < m; i++){
            if((used >> i) & 1) continue;
            vector<int> u, v;
            for(auto &it: a){
                if((it >> i) & 1) u.emplace_back(it);
                else v.emplace_back(it);
            }
            res = min(res, max(f(used | 1 << i, u), f(used | 1 << i, v))+1);
        }
        mem[{used, a}] = res;
        return res;
    }

    void solve(){
        cout << f(0, a) << '\n';
    }
};

int main(){
    while(true){
        int m, n;
        cin >> m >> n;
        if(m == 0 && n == 0) break;
        
        Solver sol(n, m);
        sol.solve();
    }
    return 0;
}
accuracy: 1
time_ms: 520
memory_kb: 6932
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
template<class T> inline T read(T&x){
    T data=0;
    int w=1;
    char ch=getchar();
    while(ch!='-'&&!isdigit(ch))
        ch=getchar();
    if(ch=='-')
        w=-1,ch=getchar();
    while(isdigit(ch))
        data=10*data+ch-'0',ch=getchar();
    return x=data*w;
}
const int maxn=150;
int m,n;
int feature[maxn],cnt[(1<<11)+10][(1<<11)+10];
int d[(1<<11)+10][(1<<11)+10];

int dp(int s,int a){
    if(d[s][a]!=-1)return d[s][a];
    if(cnt[s][a]<=1)return d[s][a]=0;
    if(cnt[s][a]==2)return d[s][a]==1;
    int ans=20;
    for(int i=0;i<m;++i)
        if(!(s&(1<<i)))ans=min(ans, max(dp(s|(1<<i),a),dp(s|(1<<i),a|(1<<i)))+1 );
    return d[s][a]=ans;
}
int main(){
    while(read(m)&&read(n)){
        memset(feature,0,sizeof(feature));
        char s[20];
        for(int i=1;i<=n;++i){
            scanf("%s",s);
            for(int j=0;j<m;++j)
                feature[i]|=((s[j]-'0')<<j);
        }
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<(1<<m);++i)
            for(int j=1;j<=n;++j)
                ++cnt[i][i&feature[j]];
        memset(d,-1,sizeof(d));
        printf("%d\n",!dp(0,0)?0:dp(0,0)+1);
    }
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 36260
final_rank: 18