/**************************************************************** 
 * Description: P1571  二分法
 解题思路
输入处理：

首先读取两个整数 n 和 m，分别表示获得科技创新奖和特殊贡献奖的人数。
接下来读取两个整数数组，分别存储获得科技创新奖和特殊贡献奖的人的编号。
查找获奖重叠：

使用二分查找算法来判断某个编号是否同时出现在两个名单中。具体方法是：
先将特殊贡献奖名单排序。
对每个科技创新奖名单中的编号，使用二分查找检查是否出现在已排序的特殊贡献奖名单中。
如果编号同时出现在两个名单中，按顺序输出。
复杂度分析：

排序的时间复杂度为 O(m log m)。
每次二分查找的时间复杂度为 O(log m)，因此对 n 个元素进行二分查找的总时间复杂度为 O(n log m)。
总体时间复杂度为 O(m log m + n log m)。
 
 * Author: Alex Li
 * Date: 2024-01-22 17:33:46
 * LastEditTime: 2024-08-14 10:51:17
****************************************************************/
#include <iostream> // 包含输入输出流库
#include <algorithm> // 包含算法库，提供sort函数
#include <cmath> // 包含数学库

using namespace std;

int a[100001], b[100001]; // 定义两个数组，分别存储科技创新奖和特殊贡献奖的获奖者编号
int n, m; // 定义两个整数，分别表示科技创新奖和特殊贡献奖的获奖者数量

// 使用二分查找方法在b数组中查找是否存在编号c
bool bitSearch(int c) {
    bool d = false; // 标志位，记录是否找到编号c
    int mid; // 定义中间索引
    int l = 0, r = m; // 定义左右边界，初始为b数组的索引范围

    // 二分查找算法
    while (l <= r) {
        mid = (l + r) / 2; // 计算中间位置
        if (b[mid] == c) { // 如果中间位置的元素等于c，找到
            d = true;
            break;
        }
        if (b[mid] >= c) { // 如果中间元素大于等于c，向左半部分继续查找
            r = mid - 1;
        } else { // 如果中间元素小于c，向右半部分继续查找
            l = mid + 1;
        }
    }
    return d; // 返回是否找到c
}

int main() {
    cin >> n >> m; // 读取科技创新奖和特殊贡献奖的获奖者数量

    // 读取科技创新奖获奖者编号
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    // 读取特殊贡献奖获奖者编号
    for (int i = 0; i < m; i++) {
        cin >> b[i];
    }

    // 对特殊贡献奖名单进行排序，以便后续二分查找
    sort(b, b + m);

    // 遍历科技创新奖名单，找出同时获得两个奖项的获奖者
    for (int i = 1; i <= n; i++) {
        if (bitSearch(a[i])) cout << a[i] << ' '; // 输出同时获奖者编号
    }

    return 0;
}
