#include <bits/stdc++.h>
template <typename T>
class IntegerIterator {
 public:
  using value_type = T;
  using difference_type = std::ptrdiff_t;
  using pointer = T*;
  using reference = T;
  using iterator_category = std::input_iterator_tag;
  explicit IntegerIterator(T value) : value(value) {}
  IntegerIterator& operator++() {
    ++value;
    return *this;
  }
  IntegerIterator operator++(int) {
    IntegerIterator copy = *this;
    ++value;
    return copy;
  }
  IntegerIterator& operator--() {
    --value;
    return *this;
  }
  IntegerIterator operator--(int) {
    IntegerIterator copy = *this;
    --value;
    return copy;
  }
  T operator*() const { return value; }
  bool operator==(IntegerIterator rhs) const { return value == rhs.value; }
  bool operator!=(IntegerIterator rhs) const { return !(*this == rhs); }

 private:
  T value;
};
template <typename T>
class IntegerRange {
 public:
  IntegerRange(T begin, T end) : begin_(begin), end_(end) { ; }
  IntegerIterator<T> begin() const { return IntegerIterator<T>(begin_); }
  IntegerIterator<T> end() const { return IntegerIterator<T>(end_); }

 private:
  T begin_;
  T end_;
};
template <typename T>
class ReversedIntegerRange {
  using IteratorType = std::reverse_iterator<IntegerIterator<T>>;

 public:
  ReversedIntegerRange(T begin, T end) : begin_(begin), end_(end) { ; }
  IteratorType begin() const {
    return IteratorType(IntegerIterator<T>(begin_));
  }
  IteratorType end() const { return IteratorType(IntegerIterator<T>(end_)); }

 private:
  T begin_;
  T end_;
};
template <typename T>
IntegerRange<T> range(T to) {
  return IntegerRange<T>(0, to);
}
template <typename T>
IntegerRange<T> range(T from, T to) {
  return IntegerRange<T>(from, to);
}
template <typename T>
IntegerRange<T> inclusiveRange(T to) {
  return IntegerRange<T>(0, to + 1);
}
template <typename T>
IntegerRange<T> inclusiveRange(T from, T to) {
  return IntegerRange<T>(from, to + 1);
}
template <typename T>
ReversedIntegerRange<T> downrange(T from) {
  return ReversedIntegerRange<T>(from, 0);
}
template <typename T>
ReversedIntegerRange<T> downrange(T from, T to) {
  return ReversedIntegerRange<T>(from, to);
}
template <typename T>
ReversedIntegerRange<T> inclusiveDownrange(T from) {
  return ReversedIntegerRange<T>(from + 1, 0);
}
template <typename T>
ReversedIntegerRange<T> inclusiveDownrange(T from, T to) {
  return ReversedIntegerRange<T>(from + 1, to);
}
template <typename T, std::size_t N>
struct MakeVector {
  template <typename... Args,
            typename R = std::vector<decltype(MakeVector<T, N - 1>::make_vector(
                std::declval<Args>()...))>>
  static R make_vector(std::size_t first, Args... sizes) {
    auto inner = MakeVector<T, N - 1>::make_vector(sizes...);
    return R(first, inner);
  }
};
template <typename T>
struct MakeVector<T, 1> {
  template <typename R = std::vector<T>>
  static R make_vector(std::size_t size, const T& value) {
    return R(size, value);
  }
};
template <typename T, typename... Args>
auto make_vector(Args... args)
    -> decltype(MakeVector<T, sizeof...(Args) - 1>::make_vector(args...)) {
  return MakeVector<T, sizeof...(Args) - 1>::make_vector(args...);
}
template <typename T>
bool updateMin(T& oldValue, const T& newValue) {
  if (newValue < oldValue) {
    oldValue = newValue;
    return true;
  }
  return false;
}
template <typename T>
bool updateMax(T& oldValue, const T& newValue) {
  if (oldValue < newValue) {
    oldValue = newValue;
    return true;
  }
  return false;
}
template <typename T>
using range_iterator_traits = std::iterator_traits<
    typename std::decay<decltype(std::declval<T>().begin())>::type>;
template <typename R>
auto prefixSums(const R& range)
    -> std::vector<typename range_iterator_traits<R>::value_type> {
  std::vector<typename range_iterator_traits<R>::value_type> result(
      static_cast<std::size_t>(
          std::distance(std::begin(range), std::end(range)) + 1));
  std::partial_sum(std::begin(range), std::end(range), result.begin() + 1);
  return result;
}
using namespace std;
class BDvoinoeVibivanie {
 public:
  static constexpr int kStressCount = 0;
  static void generateTest(std::ostream& test) {}
  void solve(std::istream& in, std::ostream& out) {
    int n;
    in >> n;
    int k;
    in >> k;
    if (k == 0) {
      out << 0;
      return;
    }
    vector<int> is_my(1 << n);
    for (int i : range(k)) {
      int my;
      in >> my;
      --my;
      is_my[my] = true;
    }
    auto ps = prefixSums(is_my);
    vector<vector<vector<int>>> dp =
        make_vector<int>(2, 2, 1 << (n - 1), -1000000000);
    for (int i = 0; i < dp[0][0].size(); ++i) {
      int cnt = ps[2 * (i + 1)] - ps[2 * i];
      if (cnt == 0) {
        dp[0][0][i] = 0;
      }
      if (cnt >= 1) {
        dp[0][1][i] = 1;
        dp[1][0][i] = 1;
      }
      if (cnt == 2) {
        dp[1][1][i] = 1;
      }
    }
    while (dp[0][0].size() > 1) {
      auto ndp = make_vector<int>(2, 2, dp[0][0].size() / 2, -1000000000);
      for (int topl : {0, 1}) {
        for (int botl : {0, 1}) {
          for (int topr : {0, 1}) {
            for (int botr : {0, 1}) {
              for (int i : range(ndp[0][0].size())) {
                if (!topl && !topr && botl && !botr && i == 1) {
                  cerr << "Xz" << endl;
                }
                updateMax(ndp[topl || topr][botl || botr || (topl && topr)][i],
                          dp[topl][botl][i * 2] + dp[topr][botr][1 + 2 * i] +
                              (topl || topr) + (botl || botr) +
                              (botl || botr || (topl && topr)));
              }
            }
          }
        }
      }
      dp = move(ndp);
      int x;
      cerr << "here" << endl;
    }
    int ans = 0;
    for (int i : range(2))
      for (int j : range(2)) {
        ans = max(ans, dp[i][j][0] + 1);
      }
    out << ans;
  }
};
int main() {
  std::ios_base::sync_with_stdio(false);
  BDvoinoeVibivanie solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  in.tie(nullptr);
  out << std::fixed;
  out.precision(20);
  solver.solve(in, out);
  return 0;
}
