#include <bits/stdc++.h>
using namespace std;
inline void _RD(int &x) { scanf("%d", &x); }
inline void _RD(long long &x) { scanf("%lld", &x); }
inline void _RD(double &x) { scanf("%lf", &x); }
inline void _RD(long double &x) { scanf("%Lf", &x); }
inline void _RD(char &x) { scanf(" %c", &x); }
inline void RD() {}
template <class T, class... U>
inline void RD(T &head, U &...tail) {
  _RD(head);
  RD(tail...);
}
using PII = pair<int, int>;
using LL = long long;
using VI = vector<int>;
using VLL = vector<LL>;
using VVI = vector<VI>;
const int MAXN = 1007;
VI e[MAXN];
int n, m;
int ind[MAXN], oud[MAXN];
bool self[MAXN];
const int INF = 0x3f3f3f3f;
bool bfs(const int ignore, int M[], int d[]) {
  queue<int> q;
  for (auto i = (1); i <= (n); ++i)
    if (i != ignore)
      if (M[i])
        d[i] = INF;
      else
        d[i] = 0, q.push(i);
    else {
    }
  d[0] = INF;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    if (d[u] < d[0])
      for (auto v : (e[u]))
        if (v != n + ignore && d[M[v]] == INF) {
          d[M[v]] = d[u] + 1;
          q.push(M[v]);
        }
  }
  return d[0] != INF;
}
bool dfs(int u, const int ignore, int M[], int d[]) {
  if (!u) return true;
  int dt = d[u];
  d[u] = INF;
  for (auto v : (e[u]))
    if (v != n + ignore && d[M[v]] == dt + 1 && dfs(M[v], ignore, M, d)) {
      M[u] = v, M[v] = u;
      return true;
    }
  return false;
}
int hpk(int ignore) {
  int M[n << 1 | 1], d[n << 1 | 1], ans = 0;
  memset(M, 0, sizeof(M));
  while (bfs(ignore, M, d))
    for (auto i = (1); i <= (n); ++i)
      if (i != ignore && !M[i] && dfs(i, ignore, M, d)) ++ans;
  return ans;
}
int solve(int l, int r) {
  int ans = INT_MAX;
  for (auto i = (l); i <= (r); ++i) {
    int cnt = 0;
    cnt = self[i] ? 2 * n - ind[i] - oud[i] : 2 * n - ind[i] - oud[i] - 1;
    int mc = hpk(i);
    cnt = cnt + m - (ind[i] + oud[i] - self[i]) + n - 1 - 2 * mc;
    ans = min(ans, cnt);
  }
  return ans;
}
int main() {
  RD(n, m);
  for (auto i = (1); i <= (m); ++i) {
    int u, v;
    RD(u, v);
    e[u].push_back(n + v);
    ++ind[v], ++oud[u];
    if (u == v) self[u] = true;
  }
  int ans = INT_MAX;
  auto f1 = async(launch::async, solve, 1, n / 2);
  auto f2 = async(launch::async, solve, n / 2 + 1, n);
  ans = min(f1.get(), f2.get());
  printf("%d\n", ans);
  return 0;
}
