Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

// I/O
type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &Scanner{sc}
}

func (s *Scanner) nextStr() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *Scanner) nextInt() int {
	i, e := strconv.Atoi(s.nextStr())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *Scanner) nextFloat() float64 {
	f, e := strconv.ParseFloat(s.nextStr(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *Scanner) nextRuneSlice() []rune {
	return []rune(s.nextStr())
}

func (s *Scanner) nextIntSlice(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextInt()
	}
	return res
}

func (s *Scanner) nextFloatSlice(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextFloat()
	}
	return res
}

// Arithmetic
func max(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m < i {
			m = i
		}
	}
	return m
}

func min(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m > i {
			m = i
		}
	}
	return m
}

func abs(x int) int {
	if x > 0 {
		return x
	}
	return -x
}

func pow(x, y int) int {
	res := 1
	for i := 0; i < y; i++ {
		res *= x
	}
	return res
}

// Sort
type Val struct {
	id, num int
}
type ByNum []Val

func (a ByNum) Len() int           { return len(a) }
func (a ByNum) Less(i, j int) bool { return a[i].num < a[j].num }
func (a ByNum) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func main() {
	sc := NewScanner()
	wtr := bufio.NewWriter(os.Stdout)
	N, M := sc.nextInt(), sc.nextInt()
	A := sc.nextIntSlice(N)
	B := sc.nextIntSlice(M)
	And := []int{}
	Or := []int{}
	setOr := make(map[int]bool)
	for _, a := range A {
		setOr[a] = true
	}
	for _, b := range B {
		if setOr[b] {
			And = append(And, b)
		}
		setOr[b] = true
	}
	for k, _ := range setOr {
		Or = append(Or, k)
	}
	sort.Ints(Or)
	sort.Ints(And)

	fmt.Fprintln(wtr, len(And), len(Or))
	for _, v := range And {
		fmt.Fprintln(wtr, v)
	}
	for _, v := range Or {
		fmt.Fprintln(wtr, v)
	}
	wtr.Flush()
}

C++: #include <iostream>
#include <vector> 
using namespace std;

int main(void){
    int n,m;
    cin >> n >> m;
    int a[n];
    int b[m];
    vector<int> dup,all;
    
    for(int i=0;i<n;i++){
        cin >> a[i];     
    }
    for(int j=0;j<m;j++){
        cin >> b[j];
    }

    int ap=0;
    int bp=0;
    int i=0;
    int a_s=0;
    int b_s=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i and b[bp]==i) a_s++;
        if(a[ap]==i or b[bp]==i) b_s++;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }
    
    cout << a_s <<" "<< b_s << endl;
    
    ap=0;
    bp=0;
    i=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i and b[bp]==i) cout<<i<<endl;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }
    
    ap=0;
    bp=0;
    i=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i or b[bp]==i) cout<<i<<endl;

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }



    return 0;
}

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

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

    int n, m;
    cin >> n >> m;
    
    vector<int> A(n), B(m);
    set<int> st1, st2;
    for(int i = 0; i < n; i++){
        cin >> A[i];
        st1.insert(A[i]);
    }
    for(int i = 0; i < m; i++){
        cin >> B[i];
        if(st1.count(B[i])){
            st2.insert(B[i]);
        }
        st1.insert(B[i]);
    }

    cout << st2.size() << ' ' << st1.size() << endl;
    for(auto x : st2){
        cout << x << endl; 
    }
    for(auto x : st1){
        cout << x << endl;
    }

    return 0;
}

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

int main() {
  int n, m;
  cin >> n >> m;
  set<int> ans_or;
  map<int, int> mp;
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    mp[a] += 1;
    ans_or.insert(a);
  }
  set<int> ans_and;
  for (int i = 0; i < m; i++) {
    int b;
    cin >> b;
    if (mp.find(b) != mp.end()) ans_and.insert(b);
    ans_or.insert(b);
  }
  cout << ans_and.size() << ' ' << ans_or.size() << endl;
  for (auto x : ans_and) {
    cout << x << endl;
  }
  for (auto x : ans_or) {
    cout << x << endl;
  }
}

C++: //実装が重そうな問題はある程度考えてから書く
//初期化を忘れずに（特に二分探索とか）
//コーナーケースを考えて（特に場合分けとか）
//不可解すぎるバグは配列外参照（配列の長さ）を検討
#include "bits/stdc++.h"
#define YES "YES"
#define NO "NO"
#define YESNO OUT(three(solve(),YES,NO))
#define ECHO OUT(solve())
#define three(A,B,C) ((A)?(B):(C))
#define FOR(i,a,b)  for(LL i=(a);i< (LL)(b);i++)
#define EFOR(i,a,b) for(LL i=(a);i<=(LL)(b);i++)
#define RFOR(i,a,b) for(LL i=(a);i>=(LL)(b);i--)
#define REP(i,b) FOR(i,zero,b)
#define EREP(i,b) EFOR(i,zero,b)
#define RREP(i,b) RFOR(i,b-1,zero)
#define ALL(c) c.begin(),c.end()
#define UNIQUE(c) sort(ALL(c));c.erase(unique(ALL(c)),c.end())
#define MAX(c) (*max_element(ALL(c)))
#define MIN(c) (*min_element(ALL(c)))
#define MP make_pair
#define FI first
#define SE second
#define SI(x) (LL(x.size()))
#define PB emplace_back
#define DEBUG(a) OUT(a)
#define DEBUG2(a,b) OUT2(a,b)
#define cat cout << __LINE__ << endl
#define OUT(a) cout << (a) << endl
#define OUT2(a,b) cout << (a) <<" "<<(b) << endl
#define int long long
#define zero 0LL
#define pb PB
using namespace std;
template<typename T> inline bool middle(T a, T b, T c) { return b <= a && a <= c; }
template<class T> inline bool MX(T &l, const T &r) { return l < r ? l = r, 1 : 0; }
template<class T> inline bool MN(T &l, const T &r) { return l > r ? l = r, 1 : 0; }
typedef long long LL;
typedef double ld;
typedef LL ut;
typedef vector<ut> VI;
typedef vector<VI> VII;
typedef pair<ut, ut> pr;
typedef pair<ut, pr> ppr;
typedef vector<pr> Vpr;
typedef vector<ppr> Vppr;
typedef priority_queue<ppr, Vppr ,greater<ppr> > PQ;
inline void outputVI(VI x) { REP(i, SI(x)) { cout << three(i, " ", "") << x[i]; }OUT(""); }
int dx[] = { 0,1,0,-1,1,1,-1,-1,0 }, dy[] = { 1,0,-1,0,1,-1,1,-1,0 };
const int SIZE1 =3e5 + 1000;
const int SIZE2 = 2010;
const int SIZE3 = 22;
const int SIZE = SIZE1;
const LL p = 7 + 1e9;
const LL INF = 1LL << 60;
const long double EPS = 1e-7;
ut N, M, K, X, L, Y,H,W,Q,D;
// ut A,B,C,D,E,F,G,H,I,J,O,P,Q,R,T,U;
VI edges[SIZE];
LL vals[SIZE], nums[SIZE], maps[SIZE2][SIZE2], answer = zero;
//LL A[SIZE], B[SIZE];
bool nable[SIZE2][SIZE2];
LL cost[SIZE2][SIZE2];
map<LL, LL> mp;
LL solve() {
	LL n[2];
	cin >> n[0] >> n[1];
	VI v[2] = { VI(n[0]),VI(n[1]) };
	VI ans, ansb;
	REP(k,2)
	
REP(i, n[k]) {
		cin >> v[k][i];
		mp[v[k][i]] = mp[v[k][i]] + 1;
		if (mp[v[k][i]] == 1) {
			ansb.pb(v[k][i]);
		}
		else {
			ans.pb(v[k][i]);
		}
	}
	sort(ALL(ans));
	sort(ALL(ansb));
	cout << ans.size() << " " << ansb.size() << endl;
	REP(i, ans.size()) {
		cout << ans[i] << endl;
	}
	REP(i, ansb.size()) {
		cout << ansb[i] << endl;
	}
	return 0;
}
signed main() {
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(10);
	solve();
	//	cin >> N;
	return 0;
}

C++: #include <iostream>
#include <stdio.h>
#include <vector> 
using namespace std;

int main(void){
    int n,m;
    scanf("%d %d",&n,&m);
    int a[n];
    int b[m];
    vector<int> dup,all;
    
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int j=0;j<m;j++){
        scanf("%d",&b[j]);
    }

    int ap=0;
    int bp=0;
    int i=0;
    while(ap!=n or bp!=m){
        i++;
        
        if(a[ap]==i and b[bp]==i) dup.push_back(i);
        if(a[ap]==i or b[bp]==i) all.push_back(i);

        while(a[ap]<=i and ap!=n) ap++;
        while(b[bp]<=i and bp!=m) bp++;
    }
    
    cout << dup.size() <<" "<< all.size()  << endl;
    
    for(auto itr = dup.begin(); itr != dup.end(); ++itr) {
        cout << *itr << endl;
    }
    for(auto itr = all.begin(); itr != all.end(); ++itr) {
        cout << *itr << endl;
    }


    return 0;
}