#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
int V;//顶点数
vector<int> G[105];//图的邻接表表示G[i][j]:=飞行员i能和飞行员j配对
int match[105];//所匹配的顶点
bool used[105];//DFS中用到的访问标记
//向图中增加一条连接u和v的边
void add_edge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
//通过dfs寻找增广路
bool dfs(int v) {
used[v] = true;
for (int i = 0; i < G[v].size(); ++i) {
int u = G[v][i];
int w = match[u];
if (w < 0 || !used[w] && dfs(w)) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
//求解二分图的最大匹配
int bipartite_matching() {
int res = 0;
memset(match, -1, sizeof(match));
for (int v = 0; v < V; v++) {
if (match[v] < 0) {
memset(used, 0, sizeof(used));
if (dfs(v)) {
res++;
}
}
}
return res;
}
int n, m;
void input() {
//1,m:非英国飞行员
//m+1,n:英国飞行员
int s = n;
int t = s + 1;
//在源点和计算机之间连边
cin >> m >> n;
V = m;
int ti, tj;
while (cin >> ti >> tj&&(ti!=-1||tj!=-1)) {
add_edge(ti-1, tj-1);
}
}
int main() {
input();
int ans=bipartite_matching();
if (ans < 1)
cout << "No Solution!";
else
cout << ans << endl;
return 0;
}