Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

type chair struct {
	group_id, rest_time int
}

type info struct {
	group_id, num, wait_sum, before_go int
	fixed                              bool
}

func main() {
	ans := make([]int, 100)
	chair := make([]chair, 17)
	for i := 0; i < 17; i++ {
		chair[i].group_id = -1
	}
	info := make([]info, 100)
	for i := 0; i <= 99; i++ {
		info[i].group_id = i
		info[i].before_go = 5 * i
		info[i].wait_sum = 0
		if i%5 == 1 {
			info[i].num = 5
		} else {
			info[i].num = 2
		}
		info[i].fixed = false
	}
	count := 0
	FLG := 0
	tmp_num := 0
	isOK := false
	waitFLG := false
	for {
		for i := 0; i < 17; i++ {
			if chair[i].group_id != -1 {
				chair[i].rest_time--
				if chair[i].rest_time <= 0 {
					chair[i].group_id = -1
				}
			}
		}
		waitFLG = false
		count = 0
		for i := 0; i < 100; i++ {
			if info[i].fixed {
				continue
			}
			if waitFLG == false && info[i].before_go == 0 {
				FLG = -1
				tmp_num = info[i].num
				for k := 0; k <= 17-tmp_num; k++ {
					isOK = true
					for p := 0; p < tmp_num; p++ {
						if chair[k+p].group_id != -1 {
							isOK = false
							break
						}
					}
					if isOK {
						FLG = k
						break
					}
				}
				if FLG != -1 {
					for k := FLG; k < FLG+tmp_num; k++ {
						chair[k].group_id = info[i].group_id
						chair[k].rest_time = 17*(i%2) + 3*(i%3) + 19
						info[i].fixed = true
					}
				} else {
					waitFLG = true
					info[i].wait_sum++
					count++
				}
			} else {
				if info[i].before_go == 0 {
					info[i].wait_sum++
				} else {
					info[i].before_go--
				}
				count++
			}
		}
		if count == 0 {
			break
		}
	}
	for i := 0; i <= 99; i++ {
		ans[i] = info[i].wait_sum
	}
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		fmt.Println(ans[n])
	}
}

C++: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int n, a[209], b[209], e[209], ret[209];
int main() {
	for (int i = 0; i < 200; i++) {
		a[i] = (i % 5 == 1 ? 5 : 2);
		b[i] = 17 * (i % 2) + 3 * (i % 3) + 19;
	}
	int h = 0;
	fill(e, e + 200, -1);
	vector<int> s(17, -1);
	for (int i = 0; i < 1000; i++) {
		for (int j = 0; j < h; j++) {
			if (e[j] + b[j] == i) {
				for (int k = 0; k < 17; k++) {
					if (s[k] == j) s[k] = -1;
				}
			}
		}
		while (h <= i / 5) {
			bool ok = false;
			for (int k = 0; k <= 17 - a[h]; k++) {
				bool flag = true;
				for (int l = k; l < k + a[h]; l++) {
					if (s[l] != -1) flag = false;
				}
				if (flag) {
					fill(s.begin() + k, s.begin() + k + a[h], h);
					ret[h] = i - h * 5;
					e[h++] = i;
					ok = true;
					break;
				}
			}
			if (!ok) break;
		}
	}
	while (cin >> n) cout << ret[n] << endl;
	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::tuple<int,int,int> T;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

int N;
int times[100];
int chairs[17];
std::priority_queue<T,std::vector<T>,std::greater<T>> queue1, queue2; // queue1: 入っている人, queue2: 待っている人

// (1) 入れる
// (2) 次の人が入るように追い出す

int position(const T& tuple){
    for(int i=0;i+std::get<1>(tuple)<=17;i++){
        bool can = true;
        REP(j, std::get<1>(tuple)){
            if(chairs[i+j] != -1){can = false; break;}
        }
        if(can){return i;}
    }
    return -1;
}

void enter(const T& tuple, const int& pos, const int& t){
    int index = std::get<2>(tuple);
    REP(i, std::get<1>(tuple)){
        chairs[pos+i] = index;
    }
    queue1.push(std::make_tuple(t+17*(index%2)+3*(index%3)+19, std::get<1>(tuple), index));
}

void leave(const T& tuple){
    REP(i, 17){
        if(chairs[i] == std::get<2>(tuple)){chairs[i] = -1;}
    }
}

void simulate(){
    std::fill(chairs, chairs+17, -1);

    REP(i, 100){
        queue2.push(std::make_tuple(5*i, i%5==1?5:2, i));
    }

    int t = 0;
    while(!queue2.empty()){
        while(!queue1.empty()){
            T tuple = queue1.top();
            if(std::get<0>(tuple) == t){
                // printf("Exit %d %d\n", std::get<2>(tuple), t);
                queue1.pop();
                leave(tuple);
            }else{break;}
        }

        while(!queue2.empty()){
            T tuple = queue2.top();
        
            int pos = position(tuple);
            if(pos != -1 && std::get<0>(tuple) <= t){
                // printf("Enter %d %d\n", std::get<2>(tuple), t);
                queue2.pop();
                enter(tuple, pos, t);
                times[std::get<2>(tuple)] = t - std::get<0>(tuple);
            }else{
                break;
            }
        }

        t += 1;
    }
}

int main(){
    simulate();
    
    while(std::cin >> N, !std::cin.eof()){
        std::cout << times[N] << std::endl;
    }
}

C++: #include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

int main()
{
	int n;
	int ans[100], intime[100];
	int chair[17];
	
	queue<int> q;
	memset(chair, -1, sizeof(chair));
	
	int time = 0;
	while (1){
		if (time % 5 == 0) q.push(time / 5);
		
		for (int i = 0; i < 17; i++){
			int y = chair[i];
			if (y == -1) continue;
			if (time - intime[y] == 17 * (y % 2) + 3 * (y % 3) + 19)
				chair[i] = -1;
		}
		
		rep:;
		if (q.size() > 0){
			int x = q.front();
			int num;
			num = 2 + 3 * (x % 5 == 1);
			
			for (int i = 0; i <= 17 - num; i++){
				bool ok = true;
				for (int j = i; j < i + num; j++)
					if (chair[j] != -1) ok = false;
				if (ok){
					intime[x] = time; ans[x] = time - x * 5;
					if (x == 99) goto end;
					q.pop();
					for (int j = i; j < i + num; j++)
						chair[j] = x;
					goto rep;
				}
			}
		}
		time++;
	}
	end:;
	while (~scanf("%d", &n)) printf("%d\n", ans[n]);
	return (0);
}