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++: import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

    /** 対象外 */
    private static final int EXEMPT = -1;

    /** グループ数 */
    private static final int GROUP_NUM = 100;

    /** 標準入力 */
    private static BufferedReader br;

    /** 座席数 最後の座席番号 */
    private static int seatsNum, firstSeatNum;

    /** 到着時間 客数 食事時間 待ち時間 */
    private static int[] arriveMinutes, customersNum, mealMinutes, waitMinutes;

    /** 座席 */
    private static String[] seats;

    /** 初期化 */
    static {

        br = new BufferedReader(new InputStreamReader(System.in));
        seatsNum = 17;
        arriveMinutes = new int[GROUP_NUM];
        customersNum = new int[GROUP_NUM];
        mealMinutes = new int[GROUP_NUM];
        waitMinutes = new int[GROUP_NUM];
        seats = new String[seatsNum];

        for (int i = 0; i < GROUP_NUM; i++) {
            // グループ数分繰り返す

            // 到着時間
            arriveMinutes[i] = 5 * i;

            // 人数
            customersNum[i] = i % 5 == 1 ? 5 : 2;

            // 食事時間
            mealMinutes[i] = seatsNum * (i % 2) + 3 * (i % 3) + 19;

        }

        // 待ち時間を作成
        createWaitTimes();

    }

    /** 待ち時間を作成する */
    private static void createWaitTimes() {
        // 順番
        int groupOrder;

        // 行列リスト
        List<Integer> waitList = new ArrayList<Integer>();

        // 行列排除リスト
        List<Integer> removeList = new ArrayList<Integer>();

        for (int currentTime = 0, totalGroupNum = 0; totalGroupNum < GROUP_NUM; currentTime++) {
            // 行列が終了するまで、一分毎に繰り返す

            // 食事の時間が終了した客を離席させる
            outCustomer(currentTime);

            if ((groupOrder = arrivedCustomer(arriveMinutes, currentTime)) != EXEMPT) {
                // 到着時間の場合

                if (waitList.isEmpty()) {
                    // 行列がない場合

                    if (isEmpty(groupOrder)) {
                        // 着席可能の場合

                        // 座席に着席させる
                        setSeat(Integer.toString(groupOrder));

                        totalGroupNum++;

                    } else {
                        // 着席不可の場合

                        // 行列に並ばせる
                        waitList.add(groupOrder);
                    }

                } else {
                    // 行列がある場合

                    // 行列に並ばせる
                    waitList.add(groupOrder);
                }
            }

            if (!waitList.isEmpty()) {
                // 行列がある場合

                // 行列番号
                int i = 0;

                for (int wait : waitList) {
                    // 行列リスト分、繰り返す

                    if (isEmpty(wait)) {
                        // 着席可能の場合

                        // 座席に着席させる
                        setSeat(Integer.toString(wait));

                        totalGroupNum++;

                        // 待った時間を設定する
                        waitMinutes[wait] = currentTime - arriveMinutes[wait];

                        // 着席したグループを行列排除リストに追加する
                        removeList.add(i);

                    } else {
                        // 着席不可の場合

                        // 行列の先頭が着席できないため、残りの行列も着席不可にする。
                        break;
                    }
                    i++;
                }
            }

            if (!removeList.isEmpty()) {
                // 行列排除リストに着席したグループが追加されていた場合

                // リストの降順でソートする（リムーブするため）
                Collections.reverse(removeList);

                for (int remove : removeList) {
                    // 行列排除リスト分、繰り返す

                    // 行列リストから行列排除リストの番号を削除する
                    waitList.remove(remove);
                }

                // 初期化
                removeList = new ArrayList<Integer>();
            }
        }
    }

    /** メイン */
    public static void main(String[] args) throws IOException {
        String line;
        List<Integer> inputList = new ArrayList<Integer>();

        while ((line = br.readLine()) != null && !line.isEmpty()) {
            inputList.add(Integer.parseInt(line));
        }
        for (int input : inputList) {
            System.out.println(waitMinutes[input]);
        }

    }

    /** 現在時間に到着するグループ番号を検索し返す */
    private static int arrivedCustomer(int[] targets, int currentTime) {
        int order = 0;
        for (int target : targets) {
            if (target == currentTime) {
                return order;
            }
            order++;
        }
        return EXEMPT;
    }

    /** 離席させる */
    private static void outCustomer(int currentTime) {

        // 席番
        int seatNum = 0;

        for (String seat : seats) {
            // 座席数分繰り返す

            if (seat == null) {
                // 空席の場合
                seatNum++;
                continue;
            }

            if (currentTime - (arriveMinutes[Integer.parseInt(seat)]
                    + waitMinutes[Integer.parseInt(seat)]) >= mealMinutes[Integer
                        .parseInt(seat)]) {
                // 食事の時間が終了した場合

                // 空席にする
                seats[seatNum] = null;
            }
            seatNum++;
        }

    }

    /** 着席させる */
    private static void setSeat(String groupsNum) {

        for (int count = 0; count < customersNum[Integer.parseInt(groupsNum)]; count++) {
            // 着席する人数分繰り返す

            // 座席にグループ番号を設定する
            seats[firstSeatNum++] = groupsNum;
        }
    }

    /** 引数のグループ番号の客数分、空席かどうか確認する */
    private static boolean isEmpty(int groupsNum) {

        // 空席数
        int emptyseatsNum = 0;
        int i = 0;

        for (; i < seatsNum || customersNum[groupsNum] <= seatsNum - i; i++) {
            // 残座席数が客の数以下になるまで座席数分繰り返す

            if (emptyseatsNum == customersNum[groupsNum]) {
                // 連続した空席が客の数だけあった場合

                break;

            }

            if (seats[i] == null) {
                // 空席かつ繰り返す席が顧客数分以上存在する場合

                emptyseatsNum++;

                continue;

            } else {
                // 空席でない場合

                // 空席数を初期化
                emptyseatsNum = 0;
            }
        }
        if (emptyseatsNum == customersNum[groupsNum]) {
            // 空席の最初の座席番号を設定する
            firstSeatNum = i - emptyseatsNum;

            return true;
        }

        return false;
    }
}