Go: package main

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

type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	return &Scanner{sc}
}

func (sc *Scanner) NextInt() int {
	sc.sc.Scan()
	i, err := strconv.Atoi(sc.sc.Text())
	if err != nil {
		panic(err)
	}
	return i
}

func main() {
	sc := NewScanner()

	n := sc.NextInt()
	m := sc.NextInt()

	mp := map[int]int{}
	for i := 0; i < n; i++ {
		mp[sc.NextInt()]++
	}
	for i := 0; i < m; i++ {
		mp[sc.NextInt()]++
	}
	var and, or []int
	for k, v := range mp {
		if v >= 1 {
			or = append(or, k)
		}
		if v == 2 {
			and = append(and, k)
		}
	}
	sort.Ints(and)
	sort.Ints(or)
	fmt.Println(len(and), len(or))
	for _, v := range and {
		fmt.Println(v)
	}
	for _, v := range or {
		fmt.Println(v)
	}
}

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

// varibable settings
#define int long long
const int INF=1e18;
const int MOD=1e9+7;

// define basic macro {{{
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define _rrep(i,n) rrepi(i,0,n)
#define rrepi(i,a,b) for(int i=(int)((b)-1);i>=(int)(a);--i)
#define rrep(...) _overload3(__VA_ARGS__,rrepi,_rrep,)(__VA_ARGS__)
#define each(i,a) for (auto&& i : a)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define mt(a, b, c) make_tuple(a, b, c)
#define ceil(a,b) ((a)+(b)-1)/(b)
#define is_in(x, a, b) ((a)<=(x) && (x)<(b))
#define uni(x) sort(all(x));x.erase(unique(all(x)),x.end())
#define ub upper_bound
#define lb lower_bound
#define posl(A, x) (lower_bound(all(A), x)-A.begin())
#define posu(A, x) (upper_bound(all(A),x)-A.begin())
template<class T> inline void chmax(T &a, const T &b) { if((a) < (b)) (a) = (b); }
template<class T> inline void chmin(T &a, const T &b) { if((a) > (b)) (a) = (b); }

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef long double ld;
typedef pair<int,int> pii;
typedef tuple<int,int,int> iii;

template<typename T> using PQ = priority_queue<T, vector<T>, greater<T>>;
struct Fast { Fast(){ std::cin.tie(0); ios::sync_with_stdio(false); } } fast;

#if defined(PCM) || defined(LOCAL)
  #include "lib/dump.hpp"
#else
  #define dump(...) 42
  #define dump_1d(...) 42
  #define dump_2d(...) 42
#endif
//}}}

signed main() {
  int n,m;cin>>n>>m;
  map<int, int> d;
  vector<int> a(n);
  rep(i, n) {
    cin>>a[i];
    d[a[i]]++;
  }
  dump(a);
  vector<int> b(m);
  rep(i, m) {
    cin>>b[i];
    d[b[i]]++;
  }
  dump(b);

  vi vor, vand;
  each(el, d){
    vor.pb(el.first);
    if (el.second==2) vand.pb(el.first);
  }
  dump(vand);
  dump(vor);
  cout << sz(vand) << " " << sz(vor) << endl;
  rep(i, sz(vand)) cout << vand[i] << endl;
  rep(i, sz(vor)) cout << vor[i] << endl;
  return 0;
}

C++: #include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>
#include <iterator>
#pragma warning(disable:4996)
 
typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
#define MOD 1000000007
using namespace std;


int main(int argc, char* argv[])
{
    long n, m;
    scanf("%ld%ld", &n, &m);

    vector<long> aa, bb;
    long i;
    for(i=0; i<n; i++) {
        long tmp;
        scanf("%ld", &tmp);
        aa.push_back(tmp);
    }
    sort(aa.begin(), aa.end());
    for(i=0; i<m; i++) {
        long tmp;
        scanf("%ld", &tmp);
        bb.push_back(tmp);
    }
    sort(bb.begin(), bb.end());

    vector<long> cc;
    set_intersection(aa.begin(), aa.end(), bb.begin(), bb.end(), back_inserter(cc));

    vector<long> dd;
    set_union(aa.begin(), aa.end(), bb.begin(), bb.end(), back_inserter(dd));

    printf("%ld %ld\n", (long)cc.size(), (long)dd.size() );
    for(i=0; i<(long)cc.size(); i++) {
        printf("%ld\n", cc[i]);
    }

    for(i=0; i<(long)dd.size(); i++) {
        printf("%ld\n", dd[i]);
    }

    return 0;
}

C++: #include <bits/stdc++.h>
#define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,NAME,...) NAME
#define pr(...) cerr<< GET_MACRO(__VA_ARGS__,pr8,pr7,pr6,pr5,pr4,pr3,pr2,pr1)(__VA_ARGS__) <<endl
#define pr1(a) (#a)<<"="<<(a)<<" "
#define pr2(a,b) pr1(a)<<pr1(b)
#define pr3(a,b,c) pr1(a)<<pr2(b,c)
#define pr4(a,b,c,d) pr1(a)<<pr3(b,c,d)
#define pr5(a,b,c,d,e) pr1(a)<<pr4(b,c,d,e)
#define pr6(a,b,c,d,e,f) pr1(a)<<pr5(b,c,d,e,f)
#define pr7(a,b,c,d,e,f,g) pr1(a)<<pr6(b,c,d,e,f,g)
#define pr8(a,b,c,d,e,f,g,h) pr1(a)<<pr7(b,c,d,e,f,g,h)
#define prArr(a) {cerr<<(#a)<<"={";int i=0;for(auto t:(a))cerr<<(i++?", ":"")<<t;cerr<<"}"<<endl;}
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL<<60)+1e9; // ~ 1.15 * 1e18
const Int mod = (1e9)+7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int,Int>;
template<class T> T Max(T &a,T b){return a=max(a,b);}
template<class T> T Min(T &a,T b){return a=min(a,b);}
template<class T1, class T2> ostream& operator<<(ostream& o,pair<T1,T2> p){return o<<"("<<p.first<<","<<p.second<<")";}
template<class T1, class T2, class T3> ostream& operator<<(ostream& o,tuple<T1,T2,T3> t){
  return o<<"("<<get<0>(t)<<","<<get<1>(t)<<","<<get<2>(t)<<")";}
template<class T1, class T2> istream& operator>>(istream& i,pair<T1,T2> &p){return i>>p.first>>p.second;}
template<class T> ostream& operator<<(ostream& o,vector<T> a){Int i=0;for(T t:a)o<<(i++?" ":"")<<t;return o;}
template<class T> istream& operator>>(istream& i,vector<T> &a){for(T &t:a)i>>t;return i;}
//INSERT ABOVE HERE


signed main(){
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);


  int n, m;
  cin>>n>>m;
  vector<int> A(n);
  vector<int> B(m);
  cin>>A>>B;

  int i = 0, j = 0;
  int ans1 = 0;
  vector<int> V;
  while(i < n && j < m){
    if(i < n && A[i] < B[j]) i++;
    else if(j < m && A[i] > B[j])j++;
    else ans1++, V.push_back(A[i]), i++, j++;
  }

  set<int> S;
  for(int i=0;i<n;i++) S.insert(A[i]);
  for(int i=0;i<m;i++) S.insert(B[i]);
  int ans2 = S.size();
  cout<<ans1<<" "<<ans2<<endl;

  for(int i=0;i<(int)V.size();i++) cout<<V[i]<<endl;
  for(auto p:S) cout<<p<<endl;
  
  
  return 0;
}